0

Say, I want an array of words that is of max length 20. I get the number of words to be stored from user input. What is the most memory efficient way to declare the above array?

I could do something like this, but I guess its not very memory efficient?

char wordArray[1000][20];

That is I want "1000" to varies accordingly to user's input. And I can't do this.

int main()
{
    int size;
    printf("Enter size: ");
    scanf("%d", &size);
    char wordArray[size][20];
}
Gavin
  • 2,784
  • 6
  • 41
  • 78
  • I'm afraid we're going to need some more info here. What kind of input? Is the size of the input known beforehand *at runtime* (I know it's not at compile-time)? – Tim Čas Feb 16 '15 at 14:21
  • 3
    I guess you need to `malloc` it – n0p Feb 16 '15 at 14:21
  • [like this](http://stackoverflow.com/questions/7871081/how-to-declare-an-array-with-an-arbitrary-size) – David K-J Feb 16 '15 at 14:23
  • 1
    Funny thing is, you *can* do this in a C99-complying compiler. However, it's not really good practice... –  Feb 16 '15 at 14:24

2 Answers2

4

Generally stack size is small and you can't allocate such a big amount of memory on stack. Doing so will result in stack overflow. You need dynamic allocation.

int size;
printf("Enter size: ");
scanf("%d", &size);
char **wordArray = malloc(size*sizeof(char *));

for(int i = 0; i < size; i++)
     wordArray[i] = malloc(20);  

Call free to deallocate.

But, note that this will allocate defragmented memory instead of continuous unlike as in case of 2D array. To get continuous memory allocation you can use pointer to array as

int (*wordArray)[20] = malloc(size * sizeof(*wordArray));  

and access the element as wordArray[i][j].

For more detailed explanation read c-faq 16.6: How can I dynamically allocate a multidimensional array?

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    Beat me to it :) Use malloc. And don't forget to **free()** your wordArray when you're done with it. – James Adam Feb 16 '15 at 14:23
  • Dumb question, but: why is it necessary to declare a pointer to a pointer to char here instead of just pointer to char? – Unheilig Feb 16 '15 at 15:00
  • 1
    @Unheilig; To achieve the effect of two dimensional array. – haccks Feb 16 '15 at 15:04
  • I would not recommend to use a pointer-to-pointer based lookup table fragmented all over the heap. Instead, [allocate a 2D array](http://stackoverflow.com/questions/28317035/double-free-or-corruption-3d-array-in-c/28318050#28318050). The OP requested a 2D array, not a fragmented lookup table. – Lundin Feb 16 '15 at 15:24
  • You can easily tell that the lookup table does not "achieve the effect" of a 2D array by: `char stack_array[1000][20]; memcpy(stack_array, wordArray, sizeof(stack_array)); // crash & burn because wordArray is not an array.` – Lundin Feb 16 '15 at 15:31
  • @Lundin; Well you are right that it will allocate defragmented memory but the actual question of OP is to allocate huge memory which is not possible on stack without changing its size somehow and that's why answer was focused on dynamic allocation instead of continuous allocation of memory. – haccks Feb 16 '15 at 15:54
2

Nope, it is not, because you're imposing an allocation of 100000 times sizeof(char) of memory. And no, you can't do as you wrote here, because during the compile-time the size of array is unknown, so space cannot be allocated. You could do it using malloc.

Michał Szydłowski
  • 3,261
  • 5
  • 33
  • 55
  • He could do it as he wrote there in C99, *BUT* (and it's a big "but"), it's prone to stack overflows and so on --- so, while not impossible, it'd be a bad idea nevertheless. – Tim Čas Feb 16 '15 at 14:24