Dynamically allocated array of structures in C - c

I just wanted to know if the following works. I have a struct
called foo that is defined as the following:
struct foo {
char name[255];
int amount;
};
During runtime, I need to create an array of the above structures whose size is dependent on a value I receive from a file's input. Let's say this size is k. Will the following code appropriately allocate a dynamically-sized array of structures?
struct foo *fooarray;
fooarray = malloc(k * sizeof(struct foo));
EDIT: If I want to access members of the structures within these arrays, will I use the format fooarray[someindex].member?

That will work (and your accessing is correct). Also, you can guard against size errors by using the idiom:
fooarray = malloc(k * sizeof *fooarray);
Consider using calloc if it would be nice for your items to start out with zero amounts and blank strings, instead of garbage.
However, this is not a VLA. It's a dynamically-allocated array. A VLA would be:
struct foo fooarray[k];

Yes it will.
On failure it will return 0.
And you have to free the memory returned by malloc when you are done with it
You can access the first member:
fooarray[0].name
fooarray[0].amount
The second as:
fooarray[1].name
fooarray[1].amount
etc..

One more different notation can be used in this approach:
struct foo {
char name[255];
int amount;
};
int main (void)
{
struct foo *fooarray;
struct foo *fooptr[5];
unsigned int i = 0;
for (i = 0; i < 5; i++)
fooptr[i] = malloc(1* sizeof(struct foo));
fooptr[2]->name[3] = 'A';
printf ("\nfooptr[2]->name[3]=%c\n",fooptr[2]->name[3]);
}

Related

How to allocate memory dynamically for a struct [duplicate]

I have looked around but have been unable to find a solution to what must be a well asked question.
Here is the code I have:
#include <stdlib.h>
struct my_struct {
int n;
char s[]
};
int main()
{
struct my_struct ms;
ms.s = malloc(sizeof(char*)*50);
}
and here is the error gcc gives me:
error: invalid use of flexible array member
I can get it to compile if i declare the declaration of s inside the struct to be
char* s
and this is probably a superior implementation (pointer arithmetic is faster than arrays, yes?)
but I thought in c a declaration of
char s[]
is the same as
char* s
The way you have it written now , used to be called the "struct hack", until C99 blessed it as a "flexible array member". The reason you're getting an error (probably anyway) is that it needs to be followed by a semicolon:
#include <stdlib.h>
struct my_struct {
int n;
char s[];
};
When you allocate space for this, you want to allocate the size of the struct plus the amount of space you want for the array:
struct my_struct *s = malloc(sizeof(struct my_struct) + 50);
In this case, the flexible array member is an array of char, and sizeof(char)==1, so you don't need to multiply by its size, but just like any other malloc you'd need to if it was an array of some other type:
struct dyn_array {
int size;
int data[];
};
struct dyn_array* my_array = malloc(sizeof(struct dyn_array) + 100 * sizeof(int));
Edit: This gives a different result from changing the member to a pointer. In that case, you (normally) need two separate allocations, one for the struct itself, and one for the "extra" data to be pointed to by the pointer. Using a flexible array member you can allocate all the data in a single block.
You need to decide what it is you are trying to do first.
If you want to have a struct with a pointer to an [independent] array inside, you have to declare it as
struct my_struct {
int n;
char *s;
};
In this case you can create the actual struct object in any way you please (like an automatic variable, for example)
struct my_struct ms;
and then allocate the memory for the array independently
ms.s = malloc(50 * sizeof *ms.s);
In fact, there's no general need to allocate the array memory dynamically
struct my_struct ms;
char s[50];
ms.s = s;
It all depends on what kind of lifetime you need from these objects. If your struct is automatic, then in most cases the array would also be automatic. If the struct object owns the array memory, there's simply no point in doing otherwise. If the struct itself is dynamic, then the array should also normally be dynamic.
Note that in this case you have two independent memory blocks: the struct and the array.
A completely different approach would be to use the "struct hack" idiom. In this case the array becomes an integral part of the struct. Both reside in a single block of memory. In C99 the struct would be declared as
struct my_struct {
int n;
char s[];
};
and to create an object you'd have to allocate the whole thing dynamically
struct my_struct *ms = malloc(sizeof *ms + 50 * sizeof *ms->s);
The size of memory block in this case is calculated to accommodate the struct members and the trailing array of run-time size.
Note that in this case you have no option to create such struct objects as static or automatic objects. Structs with flexible array members at the end can only be allocated dynamically in C.
Your assumption about pointer aritmetics being faster then arrays is absolutely incorrect. Arrays work through pointer arithmetics by definition, so they are basically the same. Moreover, a genuine array (not decayed to a pointer) is generally a bit faster than a pointer object. Pointer value has to be read from memory, while the array's location in memory is "known" (or "calculated") from the array object itself.
The use of an array of unspecified size is only allowed at the end of a structure, and only works in some compilers. It is a non-standard compiler extension. (Although I think I remember C++0x will be allowing this.)
The array will not be a separate allocation for from the structure though. So you need to allocate all of my_struct, not just the array part.
What I do is simply give the array a small but non-zero size. Usually 4 for character arrays and 2 for wchar_t arrays to preserve 32 bit alignment.
Then you can take the declared size of the array into account, when you do the allocating. I often don't on the theory that the slop is smaller than the granularity that the heap manager works in in any case.
Also, I think you should not be using sizeof(char*) in your allocation.
This is what I would do.
struct my_struct {
int nAllocated;
char s[4]; // waste 32 bits to guarantee alignment and room for a null-terminator
};
int main()
{
struct my_struct * pms;
int cb = sizeof(*pms) + sizeof(pms->s[0])*50;
pms = (struct my_struct*) malloc(cb);
pms->nAllocated = (cb - sizoef(*pms) + sizeof(pms->s)) / sizeof(pms->s[0]);
}
I suspect the compiler doesn't know how much space it will need to allocate for s[], should you choose to declare an automatic variable with it.
I concur with what Ben said, declare your struct
struct my_struct {
int n;
char s[1];
};
Also, to clarify his comment about storage, declaring char *s won't put the struct on the stack (since it is dynamically allocated) and allocate s in the heap, what it will do is interpret the first sizeof(char *) bytes of your array as a pointer, so you won't be operating on the data you think you are, and probably will be fatal.
It is vital to remember that although the operations on pointers and arrays may be implemented the same way, they are not the same thing.
Arrays will resolve to pointers, and here you must define s as char *s. The struct basically is a container, and must (IIRC) be fixed size, so having a dynamically sized array inside of it simply isn't possible. Since you're mallocing the memory anyway, this shouldn't make any difference in what you're after.
Basically you're saying, s will indicate a memory location. Note that you can still access this later using notation like s[0].
pointer arithmetic is faster than arrays, yes?
Not at all - they're actually the same. arrays translate to pointer arithmetics at compile-time.
char test[100];
test[40] = 12;
// translates to: (test now indicates the starting address of the array)
*(test+40) = 12;
Working code of storing array inside a structure in a c, and how to store value in the array elements Please leave comment if you have any doubts, i will clarify at my best
Structure Define:
struct process{
int process_id;
int tau;
double alpha;
int* process_time;
};
Memory Allocation for process structure:
struct process* process_mem_aloc = (struct process*) malloc(temp_number_of_process * sizeof(struct process));
Looping through multiple process and for each process updating process_time dyanamic array
int process_count = 0;
int tick_count = 0;
while(process_count < number_of_process){
//Memory allocation for each array of the process, will be containting size equal to number_of_ticks: can hold any value
(process_mem_aloc + process_count)->process_time = (int*) malloc(number_of_ticks* sizeof(int));
reading data from line by line from a file, storing into process_time array and then printing it from the stored value, next while loop is inside the process while loop
while(tick_count < number_of_ticks){
fgets(line, LINE_LENGTH, file);
*((process_mem_aloc + process_count)->process_time + tick_count) = convertToInteger(line);;
printf("tick_count : %d , number_of_ticks %d\n",tick_count,*((process_mem_aloc + process_count)->process_time + tick_count));
tick_count++;
}
tick_count = 0;
the code generated will be identical (array and ptr). Apart from the fact that the array one wont compile that is
and BTW - do it c++ and use vector

Changing the size of struct after declared

I have a code contains this structure
struct mystruct{
int a;
int array[1];
};
Directly, after running the code
I mean I will not declare any variable of that structure,the user will enter a number, for example 6.
What I want is to know how I can change the size of that structure.
Like I declared on this form
struct mystruct{
int a;
int array[6];
};
Then I use normally, like this:
struct mystruct var;
//I do not want to add any code here, to appropriate new form
for(int i=0;i<6;i++)
var.array[i]=0;
The typical way to do something like this in straight C (as opposed to C++) is to have just a pointer member in the struct, to point to the array, and then another member of the struct to indicate the size. This generally requires users of the struct to malloc() the array as needed, and to also set the size member to match. Something like:
struct mystruct
{
int size;
int *array;
};
and:
struct mystruct var;
var.array = malloc(6 * sizeof(int));
var.size = 6;
for (int i = 0; i < var.size; i++)
var.array[i] = 0;
Another common paradigm is a linked list.
Of course, in C++ you could just use a std::vector<int>.
You cannot change the declaration of the struct but if it is a variable length array within a struct that you want you do have an option. Declare your struct as:
struct mystruct{
int a;
int array[0];
};
And then when you want to create an instance with n elements in the array do the following:
struct mystruct *a = malloc(sizeof(struct mystruct) + n * sizeof(int));
This will create a memory region large enough to hold the struct and an array of length n. You can then use the array just as you would any other array:
a->array[1] = 5;
(this example assumes the array has at least 2 elements)
To accomplish what you have in your code example you would want to do something like this:
struct mystruct *var = malloc(sizeof(struct mystruct) + 6 * sizeof(int));
for(int i=0;i<6;i++) {
var->array[i]=0;
}
You cannot change an already declared struct, but you can make a new one as you want by modifying the program. You can't change data structures used in the program on the fly while it is running.

How to correctly define an array of structures?

i have the following structure:
typedef struct Course {
int course_id;
char* course_name;
int prior_course_id;
StudentTree* students;
} Course;
and the following function i need to implement:
void createReport(FILE* courses[], int numOfCourses, FILE* studentFile, char* reportFileName
as you can see i get an array of FILE*, each cell contains different file pointer.
my intention is to create an array that each cell is Course* type, and initialize each cell with a Course struct containing the data read from the courses files.
what is the correct way to declare it inside the function?
do i need to dynamically allocate memory for it, or it can be done in compilation?
i've tried
Course* course_array[numOfCourses] = {NULL};
Course* course_array[numOfCourses] = NULL;
but it won't compile.
thanks for your help
You declare an array of structs the same way you declare an array of ints or FILE *s:
Type variableName[numberOfElements];
Before C99 (and barring compiler specific extensions), creating an array with a variable number of elements on the stack wasn't supported. So make sure that you are targeting the correct standard. In your case, assuming C99 support, the following should work:
Course *course_array[numOfCourses];
Because you intend to initialize each of the elements in the array, there is no need to zero them out.
You would then access the elements like this:
course_array[0] = malloc(sizeof(Course))
course_array[0]->course_id = 2;
/* etc. */
Now if you can't assume C99 support, things get a bit more tricky but not much:
Course *course_array = malloc(sizeof(Course *) * numOfCourses);
After that you can access course_array with the same array notation:
course_array[0] = malloc(sizeof(Course))
course_array[0]->course_id = 42;
/* etc. */
Once you're doing with the array, you'll need to make sure that you free any of the memory that you allocated:
for (i = 0; i < numOfCourses; i++) {
free(course_array[i]);
}
/* If you malloc'd course_array, then you need this too */
free(course_array);
Course* course_array[numOfCourses] = {NULL};
This is good, but it creates array of Course *. So you need to allocate memory for each pointer in course_array before accessing it.
Something like
course_array[0] = malloc(sizeof(Course));
course_array[0]->course_id = someid;
When you define the array in the first place, you shouldn't need to allocate memory. You're defining the array on the stack, and the elements of the array are just pointers.
I think what you should do is first define the array, and then initialize each element with a malloc call. For example:
Course* course_array[numOfCourses];
for(int i = 0; i < numOfCourses, i++) {
course_array[i] = (Course*)malloc(sizeof(Course));
My favorite way:
typedef struct {
int a;
char b;
float c;
}DATA;
//then use typdef'ed DATA to create array (and a pointer to same)
DATA data[10], *pData;
//then, in function, you can initialize the pointer to first element of array this way:
int main(void)
{
pData = &data[0];
return 0;
}
Your example code would look like this:
typedef struct {
int course_id;
char* course_name;
int prior_course_id;
StudentTree* students;
} COURSE;
//then in function:
COURSE course[numOfCourses]

What is the proper way to use memset on a struct element?

I'm trying to use memset on a struct element like so:
memset( &targs[i]->cs, 0, sizeof( xcpu ) );
However, doing so gives me a segmentation fault. I neither understand why this is failing, nor how I can make it work. What is the proper way to use memset on an element of a struct, and why does my method not work?
Line which allocates memory for targs:
eargs **targs = (eargs **) malloc(p * sizeof(eargs *));
Struct definitions for struct element cs (xcpu_context) and struct targs (execute_args):
typedef struct xcpu_context {
unsigned char *memory;
unsigned short regs[X_MAX_REGS];
unsigned short pc;
unsigned short state;
unsigned short itr;
unsigned short id;
unsigned short num;
} xcpu;
typedef struct execute_args {
int ticks;
int quantum;
xcpu cs;
} eargs;
You have allocated an array of pointers in the line
eargs **targs = (eargs **) malloc(p * sizeof(eargs *));
but you haven't initialized the elements themselves. So this segfault has nothing to do with properly using memset on the fields of a struct, but instead derives from using uininitialized memory (assuming that you don't have a loop to initialize each eargs object after you allocate the array of pointers).
Instead, if you wanted to allocate a dynamic array of p eargs objects (I'm using the term "objects" loosely here), you would write
eargs *args = malloc(p * sizeof(eargs));
if (!args) {
/* Exit with an error message */
}
memset(&(args[i].cs), 0, sizeof(xcpu));
instead. Note that args is a dynamically allocated array of eargs objects, not a dynamically allocated array of pointers, so it's of type eargs * rather than eargs **.
Your memory allocation line doesn't allocate any memory for any structures, only for pointers to structures. If you want to allocate memory for that whole array, you need to add a loop to allocate memory for the structures themselves:
for (i = 0; i < p; i++)
targs[i] = malloc(sizeof(eargs));
Once you actually have structures to operate on, your memset() call should be fine.

With mmap() how can dynamically sized structures be created

Hi I have the following scenario
#define CONSTANT 10
struct structA{
int var1;
int var2[CONSTANT];
};
main(){
structA *varA = NULL;
int i;
/* some C code */
varA = mmap(0,..);
for(i = 0; i < CONSTANT; i++){
varA.var2[i] = /* C code */ ;
}
/* C code */
}
Here the number of elements in var2 array of structA is constant and hence the varA.var2[i] can be directly referenced . But If the number CONSTANT is to be determined dynamically during runtime , how should the structure definition be modified?
The cleanest way would be to use a C99 flexible array member:
struct structA{
int var1;
int var2[];
};
Then you can just mmap(NULL, sizeof(int) * (num + 1), ...). Just be careful with flexible array members, sizeof behaves funny with them (doesn't include their size).
If you can't / won't use a flexible array member, you can use a pointer instead of an array and mmap memory separately for it.
The most common way to do this is:
struct structA{
int var1;
int var2[1];
};
It's not really an array with a single element, because you allocate more memory than the size of a structA.
The number CONSTANT cannot be determined dynamically at runtime, since it affects the structure size.
The usual trick for what you're trying to do (I'm not sure if it's strictly valid C but it's very common) is to create
struct structA{
int var1;
int var2[0];
};
and when you map or allocate, allocate (sizeof(structA) + sizeof(int) * CONSTANT) bytes.

Resources