Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to set the size of an array within structure during runtime?

Tags:

arrays

c

struct

I have a structure as below:

struct Query {  
    int     pages[];
    int     currentpage;
};

I was wondering if it was possible to set the size of this array after creating the structure.

Query new = malloc(sizeof(struct Query));

After this, I will perform some calculations which will then tell me the size that pages[] needs to be. If pages[] needed to be of size 4, how can I set it as such?

like image 728
Archer Avatar asked May 12 '16 06:05

Archer


People also ask

Can we change the size of array during run time?

Size of an array If you create an array by initializing its values directly, the size will be the number of elements in it. Thus the size of the array is determined at the time of its creation or, initialization once it is done you cannot change the size of the array.

Can we change the size of an array during runtime in C?

You can't. This is normally done with dynamic memory allocation.

How do you determine the size of an array in runtime?

So deciding an array size at runtime is possible in modern C (>= C99) and code like the below is fine: int s; printf("Enter the array size: "); scanf("%d", &s); int a[s]; One obvious drawback of VLAs is that if s is quite big and the allocation of a could fail.

Can you change the size of an array after creation?

Arrays can either hold primitive values or object values. An ArrayList can only hold object values. You must decide the size of the array when it is constructed. You can't change the size of the array after it's constructed.


4 Answers

In C99 you can use Flexible array members:

struct Query {  
    int currentpage;
    int pages[]; /* Must be the last member */
};

struct Query *new = malloc(sizeof(struct Query) + sizeof(int) * 4);
like image 139
David Ranieri Avatar answered Oct 17 '22 09:10

David Ranieri


Change the type of pages member to pointer.

struct Query {  
    int *pages;
    int currentpage;
};

struct Query *test = malloc(sizeof(struct Query));

if (test != NULL)
{
   //your calculations

   test->pages = malloc(result_of_your_calcs);
   if (test->pages != NULL)
   {
      // YOUR STUFF
   }
   else
   {
      // ERROR
   }
}
else
{
   // ERROR
}

When you'll free your struct, you have to do that on the contrary.

free(test->pages);
free(test);
like image 36
LPs Avatar answered Oct 17 '22 09:10

LPs


You can use a Flexible array member (details in @AlterMann's answer) (C99+), or a Zero length array (GNU C).

Quoting from https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html,

Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure that is really a header for a variable-length object:

struct line {
   int length;
   char contents[0];
};

struct line *thisline = (struct line *)
   malloc (sizeof (struct line) + this_length);
thisline->length = this_length;

For standard C90, the linked site mentions

In ISO C90, you would have to give contents a length of 1, which means either you waste space or complicate the argument to malloc.

This means that for the code to work in standard C90/C89, char contents[0]; should be char contents[1];.

like image 5
Spikatrix Avatar answered Oct 17 '22 08:10

Spikatrix


Declare it as pointer and use malloc afterwards

struct Query {  
    int * pages;
    int   currentpage;
};

. . .

struct Query obj;
obj.pages = malloc(n * sizeof(int));   // n is the length you want
like image 2
Shreevardhan Avatar answered Oct 17 '22 09:10

Shreevardhan