I have, roughly speaking, a function prototype like this:
init_superstruct(const char *name, Superstruct **super, int num_substructs) {...
where superstruct looks like
typedef struct superstruct {
char *name,
Substruct **substructs,
int num_substructs;
} Superstruct
The function is supposed to
1) allocate memory for (and initialize) super, by...
2) ...assigning the name field of super enough memory to hold the name argument, and...
3) ...assigning the substructs field enough memory to hold an array pointers to Substructs (of size num_substructs).
My question: will the following code accomplish these goals?
*super = malloc(sizeof(*super));
*super->name = malloc(sizeof(strlen(name) + 1)));
*super->substructs = calloc(num_substructs, sizeof(Substruct));
This is literally my first foray into dynamic memory allocation. Any advice you have would be helpful for me!
First:
*super = malloc(sizeof(*super));
You want sizeof(**super). *super is a pointer, with type Superstruct *, so this won't allocate enough memory.
Really, you should probably allocate the structure normally, then assign it to the pointer separately. This will make your code much easier to write:
Superstruct *r = malloc(sizeof *r);
r->name = …
*super = r;
Second:
*super->name = malloc(sizeof(strlen(name) + 1)));
This is wrong. sizeof(strlen(name) + 1) is sizeof(int) (or perhaps sizeof(size_t); either way it's not what you want) -- strlen() won't even be called! Remove the sizeof() from this expression to make it correct.
Third: to allocate a single array of Substruct objects, define the structure member as Substruct *substructs, and allocate it using the exact code you've got right now. You don't need a double pointer unless you want an array of pointers to the structures, which is more complicated than you need.
If you really think you do need an array of pointers here (you probably don't), you need to allocate the array using sizeof(Substruct *) as the size argument to calloc(), not sizeof(Substruct).
Related
I am writing a program that has a bigger struct and a smaller struct, the smaller one holding names of friends of the person in index 0 of a 2D array in Friends. I wrote the whole thing from scratch a few times and it keeps giving me either seg fault or Thread 1: EXC_BAD_ACCESS (code=1, address=0x0).
Here are my structs:
expandBig() and expandFriends() do not assign values to the new data.
Looks like at least a problem is name assignment.
friends->name[friends->size] is not assigned a value after expandFriends(friends), so strcpy() fails.
void addFriend(Friends * friends, char * val) {
if(friends->size == friends->cap)
expandFriends(friends);
strcpy(friends->name[friends->size], val);
....
Consider using strdup()
// strcpy(friends->name[friends->size], val);
friends->name[friends->size] = strdup(val);
... and in InitializeFriends()
friend->name[i] = NULL;
Code such as below is tedious to review.
Was the size right? IDK, now have to trudge up to friend, find its type. OK that is Friends. Now look for Friends definition and see member char ** name. OK, now with char ** de-referenced we get char *. That matches codes sizeof(char*), so sizeof(char*) OK.
friend->name = realloc(friend->name, sizeof(char*) * friend->cap);
Save time. Code to the size of the de-referenced pointer, not the type. This is easier to code right, review and maintain.
Was the size right?
Yep, by construction, sizeof *(friend->name) is the right size.
// friend->name = realloc(friend->name, sizeof(char*) * friend->cap);
friend->name = realloc(friend->name, sizeof *(friend->name) * friend->cap);
// People * ret = (People*)calloc(DEFAULT_CAP, sizeof(People));
People * ret = calloc(DEFAULT_CAP, sizeof *ret);
Unclear why code sometimes casts the return from a *alloc() call and sometimes did not. The cast is not needed.
Strait to the point.
I have a struct with a string, char and int.
The struct is created dynamically because i will need it in different parts of my program.
struct A
{
char staticString[20];
char* dynamicString;
char character;
int integer;
};
I know if i want to create a struct i call:
A example = (A)malloc(sizeof(A));
In order to populate the dynamicString and int i used:
example->dynamicString = (char*)malloc(sizeof(char*));
example->integer = (int)malloc(sizeof(int));
Unfourtanetly when i tried to populate staticString and char it didn't worked.
Don't even ask what was my code for those, i tried a lot of combinations from everywhere.
In addition to that can somebody show me examples how to write/read those values?
Thanks in advance.
First things first:
You're using C, and by the way you've defined the structure, you need to declare the pointer like so:
struct A *example;
Next, malloc returns a pointer, so you need to cast to a pointer (and not to a structure):
(struct A *)malloc(sizeof(struct A));
Secondly, I'm not sure why but hey:
- you're trying to dynamically allocate an int in the structure. As I said previously, malloc returns a pointer, so in your structure you need an int pointer like so "int *integer;"
- you're trying to allocate a dynamic string, however you're not doing it properly, here is what I think you want
example->dynamicString = (char *)malloc(sizeof(char) * 10);
Where 10 is the size of your dynamic string.
Edit:
you may also populate the integer in your struct statically or dynamically, but I think you intended the static approach:
example->integer = 123;
The dynamic approach would be (assuming you have int *integer in your struct):
example->integer = (int *)malloc(sizeof(int));
*(example->integer) = 123;
Every time you create a new struct the memory in the heap is set to size of :
sizeof(char)*20 + sizeof(char pointer) +sizeof(char)+ sizeof(int).
If you want to save a string that will be pointed to by your char pointer- then you ask for allocation in heap for the size of that string- and malloc returns the pointer to that memory allocation on heap.
So, you already have a space for your char array, char pointer, char and int that was allocated when you asked to make a new struct and do not need to allocate it again.
also, keep in mind malloc returns a pointer to the allocated place on the heap- so if you malloc(sizeof(int)) you get a pointer to a memory allocation for an int on the heap- which is pointed to by a int pointer Not an int.
good luck!
I'm currently working on dynamically allocating my array of structures and I'm unsure how to continue. This is my structure:
struct Word_setup
{
char word[M];
int count;
} phrase[N];
I know malloc returns a pointer to a block of memory, but I'm not sure how this works when it comes to an array of structures.
If anyone could please clarify that would be much appreciated!
Probably you meant:
struct Word_setup {
char word[M];
int count;
};
It's a good idea to avoid defining variables in the same line as a struct definition anyway, to help with code readability.
Then you can allocate an array of these:
int main()
{
struct Word_setup *phrase = malloc(N * sizeof *phrase);
// use phrases[x] where 0 <= x < N
phrase = realloc(phrase, (N+5) * sizeof *phrase);
// now can go up to phrases[N+4]
free(phrase);
}
Of course you should check for failure and abort the program if malloc or realloc returns NULL.
If you also want to dynamically allocate each string inside the word then there are a few options; the simplest one to understand is to change char word[M] to char *word; and each time you allocate a phrase, write the_phrase.word = malloc(some_number); . If you allocate an array of words you'll need to loop through doing that for each word.
I suppose that N and M is a compile-time known constants. Then just use sizeof, .e.g.
struct Word_setup*ptr = malloc(sizeof(struct Word_setup)*N);
Maybe you want a flexible array member. Then, it should always be the last member of your struct, e.g.
struct Word_setup {
int count;
unsigned size;
char word[]; // of size+1 dimension
};
Of course it is meaningless to have an array of flexibly sized structures -you need an array of pointers to them.
Assuming we have a simple struct like:
typedef struct
{
int d1;
int d2;
float f1;
}Type;
Which is the correct when allocate memory for a new instance of it:
This:
// sizeof *t == sizeof(Type) ( gcc prints 12 bytes)
Type *t = malloc(sizeof *t);
or:
// sizeof pointer always == 4 (in my case also on gcc)
Type *t = malloc(sizeof(t));
Which is the correct?
This is the correct way:
Type *t = malloc(sizeof *t);
Why this is correct?
Because you correctly allocate a size big enough to hold a structure. *t points to a type Type.
This is incorrect way:
Type *t = malloc(sizeof(t));
Why this is Incorrect?
sizeof(t) returns size of pointer and not the actual type(i.e: not the size of the structure).
What you need to allocate is size big enough to hold a structure not size equal to pointer to structure.
Note that, Size of an pointer pointing to Any type is same on an system.
Why is the first approach better?
With the first approach, when you change Type, the malloc automatically changes size to be the correct value, you do not have to do that explicitly unlike other ways.
Also, the important part of writing an malloc call is finding the correct size that needs to be passed. The best way to do this is not to look anywhere (because that is when we make the mistake) but only at the left hand side of this malloc statement. Since, it is t in this case therefore the correct size will be sizeof(*t).
How to standardize use of malloc?
With above mentioned correct approach there is one problem say, if we want to malloc say 30 elements. Then our malloc expression becomes:
t = (T *) malloc(30 * sizeof (*T));
This is not the preferred way to write a malloc expression, because one can make a mistake which entering the number 30 in the malloc parameter. What we would like- irrespective of the number of elements required the malloc parameter should always be the standard sizeof(*x) or something similar.
So here is an approach with an example:
Suppose we have a pointer p, pointing to a single dimensional array of size 20, whose each element is struct node. The declaration will be:
struct node (*p) [20];
Now if we wish to malloc 20 elements of stuct node, and wish that pointer p should hold the return address of malloc then we have
p = (data-type of p) malloc (size of 20 elements of struct node);
To find the data type of p, for casting we just make the variable name disappear or replace p with a blank. So we now have
p = (struct node (*)[20] ) malloc(size of 20 elements of struct node);
We can't go very wrong over here because the compiler will complain if we are wrong. Finally the size! We just do the standard way we have described, that is
p = (struct node (*)[20] ) malloc(sizeof (*p));
And we are done!
Type *t = malloc(sizeof *t);
This is the correct way to allocate the amount of memory needed for a new instance.
Type *t = malloc(sizeof (t));
This will only allocate enough storage for a pointer, not an instance.
sizeof(*t), because t is of type Type* so that *t points to something of type Type.
But I would suggest to use this instead, because it's more readable and less error prone:
Type *t = malloc(sizeof(Type));
this one:
Type *t = malloc(sizeof(*t));
you allocate memory for the struct, not for a pointer.
The first is correct. Second will not allocate enough memory, because t has the size of a pointer.
Better yet is
Type *t = malloc(sizeof(Type));
Preferably: Type * t = malloc(sizeof(Type));
Arguably, sizeof *t works as well and allows you to change the actual type of *t without requiring you to modify two separate locations, but using the type rather than an expression in the initial allocation feels more readable and expressive... that's subjective, though. If you you want to keep your options open to change the type, I'd personally prefer factoring that change into the typedef rather than the variable declaration/initialization.
I am writing a light weight serialization function and need to include two variable sized arrays within this.
How should I track the size of each?
How should I define the struct?
Am I going about this all wrong?
EDIT: the result must be a contiguous block of memory
This resolves to something like
typedef struct
{
size_t arr_size_1, arr_size_2;
char arr_1[0/*arr_size_1 + arr_size_2*/];
} ...;
The size(s) should be in the front of the dynamic sized data, so that it doesn't move when expanding your array.
You cannot have 2 unknown sized arrays in your struct, so you must collapse them into one and then access the data relative from the first pointer.
typedef struct MyStruct_s
{
int variable_one_size;
void* variable_one_buf;
int variable_two_size;
void* variable_two_buf;
} MyStruct;
MyStruct* CreateMyStruct (int size_one, int size_two)
{
MyStruct* s = (MyStruct*)malloc (sizeof (MyStruct));
s->variable_one_size = size_one;
s->variable_one_buf = malloc (size_one);
s->variable_two_size = size_two;
s->variable_two_buf = malloc (size_two);
}
void FreeMyStruct (MyStruct* s)
{
free (s->variable_one_buf);
free (s->variable_two_buf);
free (s);
}
Since the data should be continuous in memory it is necessary to malloc a chunk of memory of the right size and manage it's contents more or less manually. You probably best create a struct that contains the "static" information and related management functions that do the memory management and give access to the "dynamic" members of the struct:
typedef struct _serial {
size_t sz_a;
size_t sz_b;
char data[1]; // "dummy" array as pointer to space at end of the struct
} serial;
serial* malloc_serial(size_t a, size_t b) {
serial *result;
// malloc more memory than just sizeof(serial), so that there
// is enough space "in" the data member for both of the variable arrays
result = malloc(sizeof(serial) - 1 + a + b);
if (result) {
result->sz_a = a;
result->sz_b = b;
}
return result;
}
// access the "arrays" in the struct:
char* access_a(serial *s) {
return &s->data[0];
}
char* access_b(serial *s) {
return &s->data[s->sz_a];
}
Then you could do things like this:
serial *s = ...;
memcpy(access_a(s), "hallo", 6);
access_a(s)[1] = 'e';
Also note that you can't just assign one serial to another one, you need to make sure that the sizes are compatible and copy the data manually.
In order to serialize variably-sized data, you have to have a boundary tag of some sort. The boundary tag can be either a size written right before the data, or it can be a special value that is not allowed to appear in the data stream and is written right after the data.
Which you choose depends on how much data you are storing, and if you are optimizing for size in the output stream. It is often easier to store a size before-hand, because you know how big to make the receiving buffer. If you don't then you have to gradually resize your buffer on load.
In some ways, I'd do things like Dan Olson. However:
1) I'd create the final struct by having two instances of a simpler struct that has just one variable array.
2) I'd declare the array with byte* and use size_t for its length.
Having said this, I'm still not entirely clear on what you're trying to do.
edit
If you want it contiguous in memory, just define a struct with two lengths. Then allocate a block big enough for both blocks that you want to pass, plus the struct itself. Set the two lengths and copy the two blocks immediately after. I think it should be clear how the lengths suffice to make the struct self-describing.