Initializing structure with variable length array in C - c

Does anyone know if there is a way to initialize a structure containing a variable length array without initializing the array first in a separate variable (and without using malloc)?
My structure looks like this:
struct my_struct {
int *values;
int size;
}
For now in my code I have that:
void my_function (int size) {
int values[size];
struct my_struct mystr = {
.values = values,
.size = size
};
...
}
(Array is initialized first, then the structure. This is working but it looks awkward to declare a separate variable for the array.)
This would probably work as well:
void my_function (int size) {
struct my_struct mystr = {
.values = calloc (size, sizeof (int)),
.size = size
};
...
}
(but I do not want to use mallocs)
But what I would like to write is something like:
void my_function (int size) {
struct my_struct mystr = {
.values = (int[size]){},
.size = size
};
...
}
Any idea?

First of all, note that you cannot use an array from your stack if you want to return your structure.
int values[size];
struct my_struct mystr = {
.values = values,
.size = size
};
return mystr;
This is not going to work since the lifetime of values ends when you return. The same applies if you try to store mystr in a value pointed by a parameter of your function.
Obviously you're not doing that, however I think it's worth to mention anyway.
Answer to your question: it depends on the situation.
Can you be sure that size is small? Or else your stack is going to overflow in int values[size]. Is it small and predictable? Stick with your first solution. If it can be large or dependent on user-input, definitely use malloc.
Are you in some way returning or retaining a persistent pointer to your structure or values? Use malloc (see my first remark).
Alternatively, you can also use the struct hack but then you would have to malloc the entire mystr anyway.
One more thing, you wrote:
(Array is initialized first, then the structure. This is working but
it looks awkward to declare a separate variable for the array.)
I'm not sure what you mean, but the int * is only sizeof(intptr_t), irregardless of the size of the array. So you're not allocating twice the memory for 1 array, if that's what you're thinking.

Initializer are unnamed objects initialized by the initializer list. Outside the body of a function, the object has static storage duration. So it is possible to use the address of such an object. With a little help from variadic macros you can try →
#include <stdio.h>
struct test {
int count;
int *values;
} test[] = {
#define init(...) { .count=sizeof( (int[]) {__VA_ARGS__} )/sizeof(int), .values=(int *)&(int []){__VA_ARGS__} }
init(0,1,2,3,4),
init(2,4,6,8),
init(1,3),
init(42)
};
#define test_size ((int) (sizeof test/sizeof *test))
int main(void)
{
for(int array=0; array<test_size; ++array) {
printf("array %d (%d) : [ ", array+1, test[array].count);
for(int i=0; i<test[array].count; ++i)
printf("%d ", test[array].values[i]);
puts("]");
}
return 0;
}

Related

Dynamic array in structs

I have a problem using dynamic memory in C.
I am creating a struct whose data is a number and a pointer to another struct (in short, an array of struct). The goal is for the parent struct to store an array of another struct using dynamic memory.
The problem I have is to access the cells of the created array, because I don't know if it's due to syntax issues (I'm new to C), or that I'm creating the array wrong, I can't modify the information contained in each cell of the contained array inside the parent struct. I can only modify by default the first cell.
This is my code, any idea or suggestion will be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char string[64];
void* date;
void* colour;
} DataState;
typedef struct {
int number;
DataState* array;
} Book;
Book* makeBook (int number){
int a=5;
void* auxiliary=&a;
Book* book_A=(Book*)(malloc(sizeof(Book)));
book_A->number=number;
book_A->array=(DataState*)(malloc(number*sizeof(DataState))); //creating array of structs inside main struct.
//And what I want to do is something like this, modify the information contained in cells of the array of structs of the main struct.
book_A->array[3]->date=auxiliary;
return book_A;
}
From already thank you very much.
Here:
book_A->array[3]->date=auxiliary;
you assign a value of auxiliary to the 3rd element of an array, but auxiliary is defined as
void* auxiliary=&a;
while a is an automatic variable in your function.
Automatic variables disappear at the return from the function, hence the pointer assigned to book_A->array[3]->date becomes invalid as soon as the return is executed.
If you want the data saved in a to remain valid after makeBook returns, then you must allocate it in more persistent storage than automatic. You've essentially done this:
int* foo()
{
int a = 5;
// WRONG, cannot return the address of a local variable
return &a;
}
int main(void)
{
int* a_addr = foo();
// WRONG, invokes undefined behavior
printf("a = %d\n", *a_addr);
}
If you want a to persist outside of foo, a possible option is:
int* foo()
{
int* a = malloc(sizeof *a);
// always check the return value of malloc
if (a != NULL)
{
*a = 5;
}
// this is ok. `a` is still in automatic storage, but this _returns_ its
// value, which is a pointer to data _not_ in automatic storage.
return a;
}
int main(void)
{
int* a_addr = foo();
// still must check here, malloc in `foo` could have failed. Probably
// better to design an architecture where you only check validity once
if (a_addr != NULL)
{
printf("a = %d\n", *a_addr); // prints a = 5
// don't forget to `free(a_addr)` when you're done with it, or you can
// let the OS clean up the memory when the process exits.
}
else
{
// handle error how you want
fprintf(stderr, "Out of mem!\n");
}
return 0;
}

How to use double pointers (pointer to pointer) for an array of structures properly in standard C?

I have an array of structures as a function parameter and the size of the array is dynamic. My coworker said that I'll have to use a double pointer since the values contained in the array of struct will be overwritten.
The parameter that will become a double pointer is the following :
xPIDConfig_t **pxPIDConfig
Here is what the structure looks like for the xPIDConfig_t :
typedef struct
{
ePIDType_t ePIDType;
/* Common fields for the different types of PID */
float fLowerSaturationLimit;
float fUpperSaturationLimit;
float fOldInput;
float fIError;
uint32_t ulDeltaTime;
eBool_t bSaturationEnable;
eBool_t bAntiWindupEnable;
eBool_t bNegativeErrorEmptyIError;
union
{
/* Parallel PID fields */
struct
{
float fProportionalGain;
float fIntegralGain;
float fDerivativeGain;
}xParallelPID;
/* Non-interactive PID fields */
struct
{
float fControllerGain;
uint32_t ulIntegralTime;
uint32_t ulDerivativeTime;
}xNonInteractivePID;
}xUniqueFields;
}xPIDConfig_t;
The size of the array of pxPIDConfig will vary.
But I am not sure how to malloc that double pointer or even how to use the function containing the double pointer.
I was just wondering if anyone had a good example of code of how to use a function with a double pointer array of variating size? and how to properly change the values contained in the array itself inside a function?
Right now this is how I change the values within the function :
pxPIDConfig->ePIDType = ePIDType;
pxPIDConfig->fOldInput = 0;
pxPIDConfig->fIError = 0;
pxPIDConfig->ulDeltaTime = ulDeltaTime;
pxPIDConfig->bSaturationEnable = bIsSaturationEnable;
pxPIDConfig->bAntiWindupEnable = bIsAntiWindupEnable;
pxPIDConfig->bNegativeErrorEmptyIError = bNegativeErrorEmptyIError;
when the pointer is double do I have to use double '->'? This is very confusing for me.
Thank you all for the help
/***************** EDIT ************************************
My function is working right now, but I got told I need to use memory allocation since the size of my arrays varies according to the number of loops I want to implement.
Here are the parameters of my function :
eError_t eControlCascadeInit( uint8_t ucNumberOfLoops, ePIDType_t *pePIDType, xPIDConfig_t **pxPIDConfig, float *pfLowerLimit, float *pfUpperLimit, uint32_t *pulDeltaTime, \
eBool_t *pbIsSaturationEnable, eBool_t *pbIsAntiWindupEnable, eBool_t *pbNegativeErrorEmptyIError, \
float *pfPGain, float *pfIGain, float *pfDGain, float *pfCGain, uint32_t *pulITime, uint32_t *pulDTime )
They're all arrays of size ucNumberOfLoops. All of them are read-only arrays, except for the pxPIDConfig one that is write-only. The function initializes all the xPIDConfig_t present in the array with the parameters passed to the function through array.
array[ 0 ] contains the parameters for the first PID controller being initialized.
array[ 1 ] contains the parameters for the second PID controller being initialized and so on...
It's like that for all the parameters in the function.
Hope it makes my question more clear?
Here you have an example of how to use double-pointer, to change the pointer in the function:
void allocate(xPIDConfig_t **array, size_t size)
{
*array = malloc(sizeof(**array) * size);
/* some examples how to access the struct members vi double pointer -*
(*array) -> ulDeltaTime = 100;
(**array).ulDeltaTime = 100;
(*(array + 5)) -> ulDeltaTime = 100;
array[5] -> ulDeltaTime = 100;
(*array[5]).ulDeltaTime = 100;
}
int main(void)
{
xPIDConfig_t *array;
allocate(&array, 100);
printf("%s\n", array ? "success" : "failure");
free(array);
}
You would only need a double pointer if the function reallocates the array to a different size. If the size isn't changing, you can just pass a pointer to (usually the first) element of the array, along with any size or index required by the function. For example:
extern void frobPidConfig(xPIDConfig_t *);
// 'frob' the xPIDConfig_t array elements from index a to b
void frobSomePidConfigs(xPIDConfig_t *pidconfigs, unsigned int a, unsigned int b)
{
unsigned int i;
for (i = a; i <= b; i++)
{
frobPidConfig(&pidConfigs[i]);
// Example of member access:
pidConfigs[i].ulDeltaTime = 42;
}
}
Example of calling code:
xPIDConfig_t *pidConfigs;
unsigned int n = 10; // or whatever...
pidConfigs = calloc(sizeof *pidConfigs, n);
if (!pidConfigs)
{
// Allocation error
exit(1);
}
/* ... */
frobSomePidConfigs(pidConfigs, 2, 5);
On the other hand, if the function needs to reallocate the array and initialize any new elements, it could be done using a double pointer like this:
extern void initPidConfig(xPIDConfig_t *);
void reallocPidConfigs(xPIDConfig_t **pidConfigs, unsigned int oldSize, unsigned int newSize)
{
unsigned int i;
// Reallocate to new size
xPIDConfig_t *realloced = realloc(*pidConfigs, sizeof **pidConfigs * newSize);
if (newSize && !realloced)
{
// allocation error
exit(EXIT_FAILURE);
}
*pidConfigs = realloced;
// Initialize any additional elements
for (i = oldSize; i < newSize; i++)
{
initPidConfig(*pidConfigs + i); // or: initPidConfig(&(*pidConfigs)[i]);
// Examples of member access:
(*pidConfigs)[i].bSaturationEnable = true;
(*pidConfigs + i)->bAntiWindupEnable = true;
}
}
Example of calling code:
xPIDConfig_t *pidConfigs = NULL;
// Note: realloc of the NULL pointer in *pidConfigs is OK.
reallocPidConfigs(&pidConfigs, 0, 10);
frobSomePidConfigs(pidConfigs, 2, 5);
Limited to addressing assumptions and questions regarding your title question:
"How to use double pointers (pointer to pointer) for an array of structures properly in standard C"
First, just because the function argument might have a double pointer (i.e. xPIDConfig_t **pxPIDConfig) does not mean that the variable need to be allocated memory with a double pointer, i.e. if the function eg is called like this: funcChangeParam(&pxPIDConfig); this often means that the object being passed needs to be changed in some way, requiring that the address of be passed, not the object itself. Also, if the object itself is a pointer, (such as a pointer to several instances of a struct object.) then the function used to pass the object for modification will be prototyped with arguments such as void funcChangeParam(xPIDConfig_t **pxPIDConfig); (Note the double pointer here.)
So with this function prototype Making the allocation of memory look like this:
void funcChangeParam(xPIDConfig_t **pxPIDConfig);
//allocate memory for multiple instances of struct
xPIDConfig_t *pxPIDConfig = malloc(countOfInstances * sizeof(*pxPIDConfig);
if(pxPIDConfig)
{
//use pxPIDConfig
funcChangeParam(&pxPIDConfig);pass pointer to multiple instances of struct
And references to the object members inside the calling function could use the following notation. Eg:
//in a loop or other construct where i is defined from 0 to countOfInstances - 1
(*pxPIDConfig)[i].ePIDType = ePIDType;//modification of assignment per your example
//etc.
//The following is a trivial example for illustration purposes.
//Code here uses a simplified struct, function
//prototype, and simple calling example, the concept
//of which easily translates to what you are
//asking about.
typedef struct {
int num;
}test_s;
void change(test_s **new);
int main(){
test_s *test = malloc(10*sizeof *test);
change(&test);
return 0;
}
void change(test_s **new)
{
for(int i=0;i<10;i++)
{
(*new)[i].num = (i+1)*3; //init all instances to some value
}
}

Warning: Return from incompatible pointer type

The code below is producing a compiler warning: return from incompatible pointer type. The type I'm returning seems to be the issue but I cant seem to fix this warning.
I have tried changing the type of hands to int *. Also have tried returning &hands.
int * dealDeck(int numPlayers, int numCards, int cardDeck[])
{
static int hands[MAX_PLAYERS][MAX_CARDS]={0};
int start = 0;
int end = numCards;
int player, hand, j;
int card;
for(player = 0; player < numPlayers; player++)
{
for(hand = start, j=0; hand < end; hand++,j++)
{
card = cardDeck[hand];
hands[player][j] = card;
}
start = end;
end += numCards;
}
return hands;
}
This function should return a pointer to the array "hands". This array is then passed to another function which will print out its elements.
The hands variable is not an int * this is a int **
So you need to return a int **
This is a 2d array.
First of all, you have declared return type of int *, which would mean, that you are trying to return an array, while you want to return a 2-dimensional array. The proper type for this would usually be int **, but that won't cut it here. You opted to go with static, fixed size array. That means, that you need to return pointer to some structures of size MAX_CARDS * sizeof(int) (and proper type, which is the real problem here). AFAIK, there is no way to specify that return type in C*.
There are many alternatives though. You could keep the static approach, if you specify only up to 1 size (static int *hands[MAX_PLAYERS] or static int **hands), but then you need to dynamically allocate the inner arrays.
The sane way to do it is usually "call by reference", where you define the array normally before calling the function and you pass it as a parameter to the function. The function then directly modifies the outside variables. While it will help massively, with the maintainability of your code, I was surprised to find out, that it doesn't get rid of the warning. That means, that the best solution is probably to dynamically allocate the array, before calling the function and then pass it as an argument to the function, so it can access it. This also solves the question of whether the array needs to be initialized, and whether = {0} is well readable way to do it (for multidimensional array) , since you'll have to initialize it "manually".
Example:
#include <stdio.h>
#include <stdlib.h>
#define PLAYERS 10
#define DECKS 20
void foo(int **bar)
{
bar[0][0] = 777;
printf("%d", bar[0][0]);
/*
* no point in returning the array you were already given
* but for the purposes of curiosity you could change the type from
* void to int ** and "return bar;"
*/
}
int main()
{
int **arr;
arr = malloc(sizeof(int *) * PLAYERS);
for (size_t d = 0; d < DECKS; d++) {
/* calloc() here if you need the zero initialization */
arr[d] = malloc(sizeof(int) * DECKS);
}
foo(arr);
return 0;
}
*some compilers call such type like int (*)[20], but that isn't valid C syntax

understanding how to dynamically create an array of structure and access its elements

I need to pass the address of a pointer to a structure to a function, which inturn will dynamically allocate the memory for an array of structures and fill in the values.
Now from my calling method, once i return from the func1, i should be able to iterate through the array of structure and display the value of the structure variables.
Can someone explain how to pass the address of the pointer to the structure, also iterating through the array of structures created dynamically ?
my sample code looks like this:
struct test {
int a;
int b;
};
void func1(int *n,struct test **testobj)
{
n=5;
*testobj = (struct test*) malloc(n*sizeof(struct test));
for(i=0;i<n;i++)
{
(*testobj)[i].a=1;
(*testobj)[i].b=2;
}
}
int main()
{
struct test testobj;int n;
func1(&n,&testobj);
for(i=0;i<n;i++)
{
printf("%d %d",(*testobj)[i].a,*testobj)[i].b);
}
free(testobj);
}
In main() define a pointer to a test structure:
struct test *testPtr;
To take the address of that pointer use the & address-of operator:
&testPtr;
This returns the address of the pointer and has type struct test **
You can then pass this into your function func1, which does the correct allocation (although casting malloc() is generally considered bad practice - Do I cast the result of malloc?). Other than that func1() looks good... the line...
*testobj = malloc(n*sizeof(struct test));
... is correct. *testobj dereferences your double pointer that you got by doing &testPtr, and stores the address of the new memory in your pointer. You are also correct when you dereference your double-pointer using (*testobj)[i] because [] has higher precedence than * you needed to (as you've correctly done) surround the dereference with brackets to make sure that happens before you take the index.
Thus, when func1() returns the pointer testPtr should now point to the array of n test structures you allocated and can be accessed using testPtr[i].a etc.
EDIT: Your for loop should become
for(i=0;i<n;i++)
printf("%d %d", testobj[i].a, testobj[i].b);
Your original for loop should have given you compilation errors? In the original code testobj is not a pointer, therefore dereferencing it should not be possible.
So the summary answer is in main() declare testobj as a pointer and then access the array elements as testobj[n] :)
EDIT: As eric has pointed out, remove n=5; from func1(). I think you meant *n=5 perhaps as some kind of debugging step... You probably mean to use n as the input to the function to say how many objects you want in your structure array. Either initialise n or perhaps re-define func1() to be
void func1(int n,struct test **testobj) // n is no longer a poitner, just a number
create your array of pointers to structures in declaration step itself and simply pass it to the function
struct test *testobj[10];
func1(&n,testobj);
This passes the whole array of pointers to the function
It isn't entirely clear which version you're asking for, but one of these should cover it:
/* allocate some number of tests.
*
* out_n: out parameter with array count
* returns: an array of tests
*/
struct test* allocate_some_tests(int *out_n) {
int n = 5; /* hardcoded, random or otherwise unknown to caller */
*out_n = n
struct test *t = malloc(n * sizeof(*t));
while (n--) {
t[n].a = 1;
t[n].b = 2;
}
return t;
}
/* allocate a specific number of tests.
*
* n: in parameter with desired array count
* returns: an array of tests
*/
struct test* allocate_n_tests(int n) {
struct test *t = malloc(n * sizeof(*t));
while (n--) {
t[n].a = 1;
t[n].b = 2;
}
return t;
}
Note that you can just return the allocated array, you don't need a pointer-to-pointer here.
As for calling them, and iterating over the result:
void print_tests(struct test *t, int n) {
for (; n--; t++)
printf("{%d, %d}\n", t->a, t->b);
}
int main()
{
int count1; /* I don't know how many yet */
struct test *array1 = allocate_some_tests(&count1);
print_tests(array1, count1);
int count2 = 3; /* I choose the number */
struct test *array2 = allocate_n_tests(count2);
print_tests(array2, count2);
}
Your code appears pretty much ok to me.
only edit that should make it fine is--
in place of
struct test testobj;
put the following code
struct test *testobj;
and keep the remaining as it is..!
here's the working version of what's required, here the memory is allocated in the called function just as required
#include <stdlib.h>
#include <stdio.h>
struct tests {
int a;
int b;
};
void func1(int *n,struct tests **testobj)
{
int i;
*n=5;
*testobj = (struct tests*) malloc((*n)*sizeof(struct tests));
for(i=0;i<(*n);i++)
{
(*testobj)[i].a=1;
(*testobj)[i].b=2;
}
}
int main()
{
int i;
struct tests *testobj;int n;
func1(&n,&testobj);
for(i=0;i<(n);i++)
{
printf("%d %d",(testobj)[i].a,testobj[i].b);
}
free(testobj);
}

How to declare and initialize this array of structs in C when the length is not known till runtime?

foo.c
#include "main.h"
unsigned char currentBar;
struct foo myFoo[getNumBars()];
void initMyFoo(void)
{
currentBar=(getNumBars()-1);
for(i=0; i<(sizeof(myFoo)/sizeof(myFoo[0])); i++)
{
myFoo[i].we = 1;
myFoo[i].want = 0;
myFoo[i].your = 0;
myFoo[i].soul = 0;
}
}
main.c
#include "foo.h"
unsigned char getNumBars()
{
return getDipSwitchValues();
}
initMyFoo();
(struct foo is declared in foo.h.)
This code has to execute without hard coding a number for Bars, as the number of Bars will change according to whatever the user sets his DIP switches. Right now I'm not able to initialize myFoo; I get the error "constant expression expected in initializer." Do I have to initialize it like:
struct foo myFoo[];
and change it later? If so, how do I make myFoo[] the correct length? I obviously don't have a constant available that corresponds to the desired size. Do I need to dynamically allocate this or something?
I found this similar answer but it wasn't too helpful for me - C++ a class with an array of structs, without knowing how large an array I need
struct foo* myFoo;
unsigned int myFooSize;
void initMyFoo(void)
{
myFooSize = getNumBars();
myFoo = malloc(myFooSize * sizeof(*myFoo));
for (i=0; i<myFooSize; i++) {
/* ... */
}
}
void cleanupMyFoo(void)
{
free(myFoo);
myFoo = NULL;
myFooSize = 0;
}
1 - in C99 you can use variable length arrays, which allow you to create arrays whose lengths are runtime-determined. You can also use them via compiler extensions (GCC supports them for non-C99 C and C++), but that's not a portable solution.
int someUnknownSize = 0;
/* some code that changes someUnknownSize */
struct foo myFoo[someUnknownSize];
2 - Declare a pointer that will be allocated memory at runtime with malloc or calloc.
struct foo *fooPtr = 0; /* null pointer to struct foo */
int sizeToAlloc = 0;
/* determine how much to allocate/modify sizeToAlloc */
fooPtr = malloc(sizeToAlloc * sizeof(*fooPtr));
/* do stuff with the pointer - you can treat it like you would an array using [] notation */
free(fooPtr);
I usually go for an expected maximum array size and if it's needed, just resize it:
type * a = calloc(sizeof(type),exp_array_size);
and upon pushing a new value onto the array (yeak, OK, I treat it as if it was a stack...), I check its current size against the new one:
if (current_size > max_size) {
max_size *= 2;
realloc(a,max_size*sizeof(type));
}

Resources