I was wondering if the following fuction is a safe way to get input from a user (with a specified length).

char *input(int inputSize)
{
   char str[inputSize + 2];

   /*DO STUFF HERE (i.e. GET INPUT, CHECK IF CODE IS CORRECT, ETC*/

   return &str[0];
}

Is there anything that can go wrong here seeing as I'm declaring the array inside the function?

Here you are declaring the array within the function and then returning it to the main. This kind of things always do create problems as the local variable is tried to destroy as soon as the control comes out of that function.

So its better always to create the array in main and then pass it to the function to manipulate it.So that you will be sure that the array does have an existence in main.

The problem is that it appears to be working. Will pointing to the first element of an array stop the memory from being unallocated (or whatever)?

While I have nothing against passing an array to the function, I'd rather do it this day seeing as it's a lot easier. Passing an array as well as it's length seems a bit ugly...

>The problem is that it appears to be working.
Welcome to the world of C. Just because it appears to work doesn't mean it's guaranteed to continue working.

>Will pointing to the first element of an array stop the
>memory from being unallocated (or whatever)?
No. The only reason it appears to work is because for that particular run of the program, the memory for the array hasn't been reused by the time you reference it. The next time you run the program it might be a completely different story.

>Passing an array as well as it's length seems a bit ugly...
Your method is ugly as well seeing as how on top of the primary bug (which is a bug regardless of which compiler you use), the way you create the array is non-portable. In the dominant C standard, C89, array sizes must be a compile-time constant yet you're trying to create an array with a runtime value. C89 compilers will fail to compile this code without a compiler extension allowing runtime array sizes.

The new C99 standard supports VLAs (variable length arrays), but C99 compliant compilers are in the minority. Using C99 features still makes your code non-portable.

There are three options:

/* 1) Pass a buffer to fill */
char *input ( char *buffer, size_t size )
{
  /* Fill the buffer */

  return buffer;
}
/* 2) Allocate a buffer dynamically */
char *input ( size_t size )
{
  char *buffer = malloc ( size );

  /* Fill the buffer */

  return buffer;
}
/* 3) Use a static buffer */
char *input ( size_t size )
{
  /* Assume VLAs for brevity */
  static char buffer[size + 2];

  /* Fill the buffer */

  return buffer;
}

Option 1 is ideal because it gives control of the buffer to the correct place: the calling code. It's easier to debug and maintain code that uses this method, even if you think it's uglier.

Option 2 is less than ideal because calling malloc is vastly slower than creating an array, and the calling code has to remember to free the memory when it's done. This method is error-prone.

Option 3 is less than ideal because now the function is not re-entrant. You can't use it recursively or with multiple threads because the buffer is shared across all calls to the function. This is the same effect as having a global buffer. This also uses the assumption of C99 or a compiler extension to allow runtime array sizes.

Narue, can you really dynamically allocate a static array in C99? Just seems odd. Is it only sized on the first call in your example?

Narue, can you really dynamically allocate a static array in C99? Just seems odd. Is it only sized on the first call in your example?

The C Std, 6.7.5.2:

10 ... Array objects declared with the static or extern storage-class specifier cannot have a variable length array (VLA) type.
...
static int E[m]; // invalid: static block scope VLA

It seems Option 3 illustrated "large enough" static buffer, not a VLA array...

Thanks for the help but I'm still a bit confused.

Reading your post, option 1 seems like the best way to go. However, the way you implemented it is confusing. For example, why would you return buffer at the end of the function? If you're taking it as an array, is there any need to return it?

Could you elaborate on that, and if possible, show a small example (even pseudo code will be fine)?

>If you're taking it as an array, is there any need to return it?
Notational convenience. If you don't return the buffer, you'd be forced to do this:

char buffer[N];

input ( buffer, N );
puts ( buffer );

Whereas that's an option when returning it, you can also do this:

char buffer[N];

puts ( input ( buffer ) );
This article has been dead for over six months. Start a new discussion instead.