Allocating works the same for all types. If you need to allocate an array of line structs, you do that with:
struct line* array = malloc(number_of_elements * sizeof(struct line));
In your code, you were allocating an array that had the appropriate size for line pointers, not for line structs. Also note that there is no reason to cast the return value of malloc().
Note that's it's better style to use:
sizeof(*array)
instead of:
sizeof(struct line)
The reason for this is that the allocation will still work as intended in case you change the type of array. In this case this is unlikely, but it's just a general thing worth getting used to.
Also note that it's possible to avoid having to repeat the word struct over and over again, by typedefing the struct:
typedef struct line
{
char* addr;
char* inst;
} line;
You can then just do:
line* array = malloc(number_of_elements * sizeof(*array));
Of course don't forget to also allocate memory for array.addr and array.inst.
Allocating works the same for all types. If you need to allocate an array of line structs, you do that with:
struct line* array = malloc(number_of_elements * sizeof(struct line));
In your code, you were allocating an array that had the appropriate size for line pointers, not for line structs. Also note that there is no reason to cast the return value of malloc().
Note that's it's better style to use:
sizeof(*array)
instead of:
sizeof(struct line)
The reason for this is that the allocation will still work as intended in case you change the type of array. In this case this is unlikely, but it's just a general thing worth getting used to.
Also note that it's possible to avoid having to repeat the word struct over and over again, by typedefing the struct:
typedef struct line
{
char* addr;
char* inst;
} line;
You can then just do:
line* array = malloc(number_of_elements * sizeof(*array));
Of course don't forget to also allocate memory for array.addr and array.inst.
For what you have described, You do not need to allocate memory for your struct, rather, you need to allocate memory for the members char *addr;, and char *inst;. If you want to have a single copy of that structure, the first section of code illustrates how to initialize, and assign values. If you want an array, the second code example illustrates the differences.
This illustrates how to allocate memory for the members of a single struct line:
typedef struct
{
char* addr;
char* inst;
}LINE;
LINE line;
int main(void)
{
strcpy(line.addr, "anystring"); //will fail
line.addr = malloc(80);
line.inst = malloc(80);
strcpy(line.addr, "someString");//success;
strcpy(line.inst, "someOtherString");//success;
}
For array of struct line...
typedef struct
{
char* addr;
char* inst;
}LINE; //same struct definition
LINE line[10]; //but create an array of line here.
int main(void)
{
int i;
for(i=0;i<10;i++)
{
line[i].addr = malloc(80);
line[i].inst = malloc(80);
}
for(i=0;i<10;i++)
{
strcpy(line[i].addr, "someString");
strcpy(line[i].inst, "someOtherString");
}
//when done, free memory
for(i=0;i<10;i++)
{
free(line[i].addr);
free(line[i].inst);
}
}
Added to address comment
Addressing the comment under this answer from @Adam Liss, the following code illustrates the following improvements using strdup(): 1) Uses only memory needed. 2) Performs memory creation and copy operations in one step, so the the following blocks:
for(i=0;i<10;i++)
{
line[i].addr = malloc(80);
line[i].inst = malloc(80);
}
for(i=0;i<10;i++)
{
strcpy(line[i].addr, "someString");
strcpy(line[i].inst, "someOtherString");
}
Become:
for(i=0;i<10;i++)
{
line[i].addr = strdup("someString");
line[i].inst = strdup("someOtherString");
}
One more note: Error handling was not included in examples above to avoid muddling up focus on the main concepts: But for the sake of completeness, because both malloc() and strdup() can fail, actual usage for each of these two functions, should include a test before using, eg:
Rather than
line[i].addr = strdup("someString");
line[i].inst = strdup("someOtherString");
The code should include
line[i].addr = strdup("someString");
if(!line[i].addr)
{
//error handling code here
}
line[i].inst = strdup("someOtherString");
if(!line[i].inst)
{
//error handling code here
}
c - malloc an array of struct pointers - Stack Overflow
How to malloc for an array of structs in c - Stack Overflow
c - Malloc an array inside a struct - Stack Overflow
c - Malloc an array of structs. - Stack Overflow
Videos
I would like to have a struct containing several dynamically allocated arrays. I've tried several variations of the following code:
#include<stdio.h>
#include<stdlib.h>
struct rectangle
{
int
width,
height;
int*
arr1,
arr2;
};
int main()
{
int n = 3;
struct rectangle box1 =
{
.width = 3,
.height = 4,
.arr1 = (int*) malloc( n * sizeof(int)),
.arr2 = (int*) malloc( n * sizeof(int))
};
}
However, I keep getting warning: initialization from int to int* makes integer from pointer without a cast [-Wint-conversion].
array is a slightly misleading name. For a dynamically allocated array of pointers, malloc will return a pointer to a block of memory. You need to use Chess* and not Chess[] to hold the pointer to your array.
Chess *array = malloc(size * sizeof(Chess));
array[i] = NULL;
and perhaps later:
/* create new struct chess */
array[i] = malloc(sizeof(struct chess));
/* set up its members */
array[i]->size = 0;
/* etc. */
There's a lot of typedef going on here. Personally I'm against "hiding the asterisk", i.e. typedef:ing pointer types into something that doesn't look like a pointer. In C, pointers are quite important and really affect the code, there's a lot of difference between foo and foo *.
Many of the answers are also confused about this, I think.
Your allocation of an array of Chess values, which are pointers to values of type chess (again, a very confusing nomenclature that I really can't recommend) should be like this:
Chess *array = malloc(n * sizeof *array);
Then, you need to initialize the actual instances, by looping:
for(i = 0; i < n; ++i)
array[i] = NULL;
This assumes you don't want to allocate any memory for the instances, you just want an array of pointers with all pointers initially pointing at nothing.
If you wanted to allocate space, the simplest form would be:
for(i = 0; i < n; ++i)
array[i] = malloc(sizeof *array[i]);
See how the sizeof usage is 100% consistent, and never starts to mention explicit types. Use the type information inherent in your variables, and let the compiler worry about which type is which. Don't repeat yourself.
Of course, the above does a needlessly large amount of calls to malloc(); depending on usage patterns it might be possible to do all of the above with just one call to malloc(), after computing the total size needed. Then you'd still need to go through and initialize the array[i] pointers to point into the large block, of course.
struct key* PrevKeys= malloc(345000*sizeof(struct key));
struct key* ActivityKeys= malloc(345000*sizeof(struct key));
struct key* CurKeys= malloc(345000*sizeof(struct key));
You're trying to assign the result of malloc, which is a pointer, to a struct, which is not possible. You have to declare them as pointers:
struct key *PrevKeys = malloc(345000 * sizeof(struct key));
...
and don't forget to free the memory:
free(PrevKeys);
If you're still getting errors, try to allocate just 10 elements, and if it works, you can be sure 345000 elements is too much.
Also, I'd prefer to not use sizeof(struct key) but sizeof(*PrevKeys) since it will always return the right size for PrevKeys, even if you change the type of PrevKeys.
The problem is that you're allocating space for the string, but you're not allocating the struct at all. c remains set to NULL and you're trying to dereference it.
Allocate space for the struct before assigning to its members
prod_t *c = malloc(sizeof(prod_t));
And, as a sidenote for your next-to-fix error: this field doesn't exist
c->stock
You need to allocate space for the struct before you can assign to the string member:
prod_t *c = malloc(sizeof(prod_t));
Also see Do I cast the result of malloc?
Your problem is the way you declared the struct it should be
Copystruct data
{
int *ref;
int *port;
char data[MAX_STRING];
};
and then you do
Copystruct data *p_valid;
p_valid = malloc(sizeof(struct data));
another thing is
Copyp_valid->data = malloc(sizeof(STRINGMAX));
is wrong because data is not a pointer. And sizeof(STRINGMAX) is wrong too, since STRINGMAX seems to be a macro and hence it will expand to it's value say if you have #define STRINGMAX 4 then it would expand to sizeof(4).
CopyYour definition of the struct:
struct data {
int *ref;
int *port;
char data[MAX_STRING];
}temp, valid, invalid;
should be more like this:
struct data
{
int *ref;
int *port;
char data[MAX_STRING];
};
then define the arrays similar to this:
struct data temp;
struct data* valid = NULL;
struct data* invalid = NULL;
int currentValidSize = 0;
int currentInvalidSize = 0;
struct data * validTemp = NULL;
struct data * invalidTemp = NULL;
then, each time the code needs room for (another) instance of a struct
struct data *validTemp = realloc(valid, (currentValidSize+1)* sizeof(data) );
if( NULL == validTemp )
{ // realloc failed
perrof( "realloc failed" );
// free everything, close files, etc here probably be writing a sub function
// and calling it here.
// a sub function that:
// that walks the valid and invalid arrays,
// first free'ing any malloc'd fields
// then finally free'ing the whole array
exit( EXIT_FAILURE );
}
// implied else, realloc successful
// update array size counter
currentValidSize++;
// update ptr to valid array of structs
valid = validTemp;
validTemp = NULL;
similar for adding an entry to the invalid array of structs
then update the valid array of structs from temp as:
(note the '-1' in the offset into valid[])
memcpy( &valid[currentValidSize-1], &temp, sizeof data );
// Note you will also have to perform a 'deep' copy of any areas
// that were malloc'd within the 'temp' struct
If I had your code and had to improve it, I'd go for
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
// The kernel style guide https://www.kernel.org/doc/html/v4.10/process/coding-style.html discourages typedefs for structs
typedef struct moeda {
double *return_value;
} moeda;
// return a struct here:
moeda initialize_return(int a)
{
moeda ret;
ret.return_value = malloc(a*sizeof(double));
return ret;
}
int main(void) {
long int a=250;
moeda m = initialize_return(a);
m.return_value[0] = 2000;
printf("%lf", m.return_value[0]);
return 0;
}
(it is better to have all identifiers in English).
This would be the first step to do. Then I might realize that the struct isn't really needed and replace it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
double * initialize_double_array(int a)
{
return malloc(a*sizeof(double));
}
int main(void) {
long int a=250;
double * arr = initialize_double_array(a);
arr[0] = 2000;
printf("%lf", arr[0]);
return 0;
}
OTOH, if there are other fields in the said struct, I might decide if they are supposed to be initialized along with this array or not.
Some variants:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
// The kernel style guide https://www.kernel.org/doc/html/v4.10/process/coding-style.html discourages typedefs for structs
struct moeda {
int num_values;
double *values;
};
// only fill a struct here:
// i. e. take a pre-initialized struct and work with it:
void moeda_alloc_values(struct moeda * data)
{
data->return_value = malloc(data->num_values * sizeof(double));
}
// return a struct here:
struct moeda initialize_moeda(int num)
{
struct moeda ret;
ret.num_values = num;
ret.return_value = malloc(num * sizeof(double));
// or just moeda_alloc_values(&ret);
return ret;
}
int main(void) {
long int a=250;
struct moeda m = initialize_return(a);
m.return_value[0] = 2000;
printf("%lf", m.return_value[0]);
struct moeda m2;
m2.num_values = 20;
moeda_alloc_values(&m2);
m2.return_value[0] = 2000;
printf("%lf", m2.return_value[0]);
return 0;
}
The struct returning function has the advantage that you have a "readily filled" structure after return.
The other function which modifies a struct via a pointer on it has the advantage that it can work on any, possibly pre-filled, possibly malloced struct and that it can work on single fields instead having to consider all fields.
First of all return is a reserved keyword in C and you can not use a reserved keyword as a variable name.
Second,If you want to allocate memory for array of any data type in other function then,declare a variable in the function,call malloc,allocate required space through malloc and return the address of the first element of allocated space.If you do not return the address the allocated space would not be known to the called function(here main()) and it could not be able to access the allocated memory space.You can do like this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct
{
double *var;
}moeda;
double *ini(int n)
{
double *arr;
arr = malloc(n*sizeof(*arr));
return arr;
}
int main(void){
long int a=250;
moeda m;
m.var=ini(a);
m.var[0] = 2000;
printf("%lf", m.var[0]);
return 0;
}
A struct included inside another struct is contained by copy, so you would not have to separately malloc it. If the struct contains a pointer to another struct, then you can consider allocating memory for it dynamically.
struct Point2d
{
float x;
float y;
};
struct Rect
{
struct Point2D a;
struct Point2D b;
};
struct LinkedListNode
{
struct LinkedListNode* next;
int value;
};
In struct Rect, the struct Point2D element are inserted into struct Rect and you don't have to dynamically allocate memory for them. On the contrary in the struct LinkedListNode the next element is referenced by a pointer and the memory must be dynamically allocated.
The two version are both useful, depending on the situation. There is no correct way to manage memory, it'll depend on your usage.
This same situation occurs in the case of an array. If your array is statically sized, then it can be directly included in the struct. However, if the size can vary, you must store a pointer within the struct.
struct Header
{
char magic[4];
unsigned int width;
unsigned int height;
};
struct Buffer
{
char* data;
unsigned int size;
unsigned int capacity;
};
struct Buffer* buffer_init()
{
struct Buffer* buffer = (struct Buffer*)malloc(sizeof(struct Buffer));
buffer->data = 0;
buffer->size = 0;
buffer->capacity = 0;
}
void buffer_grow(struct Buffer* buffer, size_t capacity)
{
if (capacity > buffer->capacity)
{
buffer->data = realloc(buffer->data, capacity);
buffer->capacity = capacity;
}
}
void buffer_append(struct Buffer* buffer, const char* data, unsigned int dataLen)
{
if (dataLen + buffer->size > buffer->capacity)
buffer_grow(MAX(dataLen + buffer->size, buffer->capacity * 2));
memcpy(buffer->data + buffer->size, data, dataLen);
buffer->size += dataLen;
}
The realloc function only does a shallow copy, that is pointer value is copied, but not the pointed object. One more time, how you deal with it will depend on your application.
typedef struct _A
{
int *arr;
int arrCount;
} A;
void Construct_A(A *a, int arraySize)
{
a->arrCount = arraySize;
a->arr = (int*)malloc(sizeof(int)*arraySize);
}
void Destruct_A(A *a)
{
free(a->arr);
a->arr = 0;
}
typedef struct _B
{
A *a;
} B;
void Construct_B(B *b, int arraySize_A)
{
b->a = (A*)malloc(sizeof(A));
Construct_A(b->a);
}
void Destruct_B(B *b)
{
Destruct_A(b->a);
free(b->a);
b->a = 0;
}
void main()
{
B b;
Construct_B(&b, 10);
// Use b and b->a
Destruct_B(&b);
}