I have a structure as below
typedef struct Mystruct{
char *name;
int telno;
struct Mystruct *nextp;
}data;
Now I malloc the structure
data *addnode;
addnode = malloc (sizeof(data));
Now I would add data to the char *name.
addnode->name = malloc (sizeof(MAX));
Question:Why is it required to malloc again?
I was under the assumption that malloc-ing the addnode will even allocate the memory for addnode->name but it is not so.
malloc is not deep and doesn't do recursion. So it won't allocate memory for any of the pointers inside the structure you pass.
If you think about this a bit more, you can see that must be so. You don't pass in any information about the structure you are allocating. You just pass a size for the memory block. Now, malloc doesn't even know what type of data you are allocating. It doesn't know that the block itself contains a pointer.
As for why this design choice was made, how can the library tell who owns the memory that your pointer refers to? Perhaps it's owned by that structure. Or perhaps you want to use that pointer to refer to some memory allocated elsewhere. Only you can know that which is why the responsibility falls to you. In fact your structure is a fine example of this. Probably the name member is owned by the structure, and the nextp member is not.
Allocating memory for Mystruct provides enough memory for a pointer to name. At this point we have no idea how many characters will be in a name so can't possibly allocate the memory for it.
If you want to fully allocate the structure in a single allocation, you could decide on a max size for name and change the structure definition to
#define MAX_NAME (10) /* change this as required */
typedef struct Mystruct{
char name[MAX_NAME];
int telno;
struct Mystruct *nextp;
}data;
Or, if you know the name when you allocate the struct, you could hide the need for two allocations from the caller by providing a constructor function
struct Mystruct* Mystruct_create(const char* name)
{
Mystruct* ms = malloc(sizeof(*ms));
ms->name = strdup(name);
return ms;
}
No. first malloc() allocates memory to whole structure including memory for holding pointer to name. i.e 4 bytes in 32 bit OS.
You need to allocate memory separately for holding data in it. by default that pointer will be pointing to some garbage location, if not initialized.
same case for free() too. i.e you have to free the inner blocks first, then free the memory for whole structure. There is no recursion kind of things in malloc() and free().
Related
Could someone please explain to me the difference between creating a structure with and without malloc. When should malloc be used and when should the regular initialization be used?
For example:
struct person {
char* name;
};
struct person p = {.name="apple"};
struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";
What is really the difference between the two? When would one approach be used over others?
Having a data structure like;
struct myStruct {
int a;
char *b;
};
struct myStruct p; // alternative 1
struct myStruct *q = malloc(sizeof(struct myStruct)); // alternative 2
Alternative 1: Allocates a myStruct width of memory space on stack and hands back to you the memory address of the struct (i.e., &p gives you the first byte address of the struct). If it is declared in a function, its life ends when the function exits (i.e. if function gets out of the scope, you can't reach it).
Alternative 2: Allocates a myStruct width of memory space on heap and a pointer width of memory space of type (struct myStruct*) on stack. The pointer value on the stack gets assigned the value of the memory address of the struct (which is on the heap) and this pointer address (not the actual structs address) is handed back to you. It's life time never ends until you use free(q).
In the latter case, say, myStruct sits on memory address 0xabcd0000 and q sits on memory address 0xdddd0000; then, the pointer value on memory address 0xdddd0000 is assigned as 0xabcd0000 and this is returned back to you.
printf("%p\n", &p); // will print "0xabcd0000" (the address of struct)
printf("%p\n", q); // will print "0xabcd0000" (the address of struct)
printf("%p\n", &q); // will print "0xdddd0000" (the address of pointer)
Addressing the second part of your; when to use which:
If this struct is in a function and you need to use it after the function exits, you need to malloc it. You can use the value of the struct by returning the pointer, like: return q;.
If this struct is temporary and you do not need its value after, you do not need to malloc memory.
Usage with an example:
struct myStruct {
int a;
char *b;
};
struct myStruct *foo() {
struct myStruct p;
p.a = 5;
return &p; // after this point, it's out of scope; possible warning
}
struct myStruct *bar() {
struct myStruct *q = malloc(sizeof(struct myStruct));
q->a = 5;
return q;
}
int main() {
struct myStruct *pMain = foo();
// memory is allocated in foo. p.a was assigned as '5'.
// a memory address is returned.
// but be careful!!!
// memory is susceptible to be overwritten.
// it is out of your control.
struct myStruct *qMain = bar();
// memory is allocated in bar. q->a was assigned as '5'.
// a memory address is returned.
// memory is *not* susceptible to be overwritten
// until you use 'free(qMain);'
}
If we assume both examples occur inside a function, then in:
struct person p = {.name="apple"};
the C implementation automatically allocates memory for p and releases it when execution of the function ends (or, if the statement is inside a block nested in the function, when execution of that block ends). This is useful when:
You are working with objects of modest size. (For big objects, using many kibibytes of memory, malloc may be better. The thresholds vary depending on circumstances.)
You are working with a small number of objects at one time.
In:
struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";
the program explicitly requests memory for an object, and the program generally should release that memory with free when it is done with the object. This is useful when:
The object must be returned to the caller of the function. An automatic object, as used above, will cease to exist (in the C model of computation; the actual memory in your computer does not stop existing—rather it is merely no longer reserved for use for the object) when execution of the function ends, but this allocated object will continue to exist until the program frees it (or ends execution).
The object is very large. (Generally, C implementations provide more memory for allocation by malloc than they do for automatic objects.)
The program will create a variable number of such objects, depending on circumstances, such as creating linked lists, trees, or other structures from input whose size is not known before it is read.
Note that struct person p = {.name="apple"}; initializes the name member with "apple" and initializes all other members to zero. However, the code that uses malloc and assigns to p_tr->name does not initialize the other members.
If struct person p = {.name="apple"}; appears outside of a function, then it creates an object with static storage duration. It will exist for the duration of program execution.
Instead of struct person* p_tr = malloc(sizeof(struct person));, it is preferable to use struct person *p_tr = malloc(sizeof *p_tr);. With the former, a change to the p_tr requires edits in two places, which allows a human opportunity to make mistakes. With the latter, changing the type of p_tr in just one place will still result in the correct size being requested.
struct person p = {.name="apple"};
^This is Automatic allocation for a variable/instance of type person.
struct person* p_tr = malloc(sizeof(person));
^This is dynamic allocation for a variable/instance of type person.
Static memory allocation occurs at Compile Time.
Dynamic memory allocation means it allocates memory at runtime when the program executes that line of instruction
Judging by your comments, you are interested in when to use one or the other. Note that all types of allocation reserve a computer memory sufficient to fit the value of the variable in it. The size depends on the type of the variable. Statically allocated variables are pined to a place in the memory by the compiler. Automatically allocated variables are pinned to a place in stack by the same compiler. Dynamically allocated variables do not exist before the program starts and do not have any place in memory till they are allocated by 'malloc' or other functions.
All named variables are allocated statically or automatically. Dynamic variables are allocated by the program, but in order to be able to access them, one still needs a named variable, which is a pointer. A pointer is a variable which is big enough to keep an address of another variable. The latter could be allocated dynamically or statically or automatically.
The question is, what to do if your program does not know the number of objects it needs to use during the execution time. For example, what if you read some data from a file and create a dynamic struct, like a list or a tree in your program. You do not know exactly how many members of such a struct you would have. This is the main use for the dynamically allocated variables. You can create as many of them as needed and put all on the list. In the simplest case you only need one named variable which points to the beginning of the list to know about all of the objects on the list.
Another interesting use is when you return a complex struct from a function. If allocated automatically on the stack, it will cease to exist after returning from the function. Dynamically allocated data will be persistent till it is explicitly freed. So, using the dynamic allocation would help here.
There are other uses as well.
In your simple example there is no much difference between both cases. The second requires additional computer operations, call to the 'malloc' function to allocate the memory for your struct. Whether in the first case the memory for the struct is allocated in a static program region defined at the program start up time. Note that the pointer in the second case also allocated statically. It just keeps the address of the memory region for the struct.
Also, as a general rule, the dynamically allocated data should be eventually freed by the 'free' function. You cannot free the static data.
I am developing a baremetal application. I am looking to adopt U-Boot source code for my application. I want to replace the following malloc calls found in U-Boot to statically allocate memory instead -
struct foo *ptr = malloc(sizeof(struct foo));
As per my understanding, this line only attempts to allocate enough space for one instance of the structure, and stores the address of that space in ptr.
Hence, I attempted to replace it with the following lines -
struct foo *ptr;
int struct_sz = sizeof(struct foo);
char buf[struct_sz];
ptr = &buf; //also tried ptr = buf;
However, this results in Stack Buffer Overflows with the return addresses of functions in the call stack being overwritten with junk.
How do I statically allocate memory instead of using malloc here?
What you are doing is allocating an array of characters and then having a pointer to a struct as pointing to the same memory.
While this is possible, you can run into memory alignment issues. The structure might have a requirement to start at a particular yte location. (e.g. a 32 bit int needs to start an address of a multiple of 4). A character array can start at any location.
An easier approach would be to declare a variable of struct foo and use the pointer to that variable. This variable needs to be global or static so that it will be present after the function scope is completed.
static struct foo var;
struct foo *ptr = &var;
To allocate many structs, you need a static array of structs
static struct arr[5];
struct foo *ptr = arr;
This approach will work if you allocate memory and do not free it very often. If you have many malloc and free you should consider writing your own allocator which will mimic the functionality of malloc
I have a structure:
struct generic_attribute{
int current_value;
int previous_value;
};
And a constructor which outputs a pointer to this structure:
struct generic_attribute* construct_generic_attribute(int current_value){
struct generic_attribute *ga_ptr;
ga_ptr = malloc (sizeof (struct generic_attribute));
ga_ptr->current_value = current_value;
ga_ptr->previous_value = 0;
return ga_ptr;
}
Now, in another function, I want to define a pointer and set it to point to the same address as the pointer that the above constructor outputs.
struct tagged_attribute* construct_tagged_attribute(int num_args, int *args){
...
struct generic_attribute* generic = malloc (sizeof(struct generic_attribute));
generic = construct_generic_attribute(args[0]);
...
}
It looks to me that what I am doing here is this:
1) I define a pointer "generic" and allocate a memory chunk to hold an instance of generic_attribute structure.
2) I call a function construct_generic_attribute within which, the program once again allocates a memory chunk of size of a generic_attribute structure. It outputs a pointer to this memory chunk.
3) In construct_tagged_attribute I set "generic" pointer equal to the pointer output by the construct_generic_attribute function, so now both of them point to the same memory slot.
However, it appears that I am allocating twice as much memory as I need to allocate.
Is there a way for me to allocate memory only once without getting a segmentation fault for failing to allocate space for "generic" pointer? Alternatively, am I misunderstanding what is happening in this code?
struct generic_attribute* generic = construct_generic_attribute(args[0]);
Should do the trick. Pointer variable is just that, a variable. You can trade pointer values around just like numbers.
Yes, you're misunderstanding, but I can't quite figure out what you think is happening to explain how it's wrong.
struct generic_attribute *generic = construct_generic_attribute(args[0]); a pointer is a kind of value. If you assign a pointer to another, you get two pointers to the same thing, without any allocation of memory. Since C doesn't manage memory for you, it's up to you to make sure that any object that's allocated is freed exactly once, and that you don't try to use pointers to an object after it's been freed.
Here
struct generic_attribute* generic = malloc (sizeof(struct generic_attribute));
you allocate a memory block, big enough to keep a generic_attribute structure, then store a pointer to that structure (technically: an address of the block) in the generic variable. Note: you do not initialize the structure members.
Then in
generic = construct_generic_attribute(args[0]);
you call a function, which internally allocates (another) block of memory and initializes it and returns a pointer to it (which was stored in a ga_ptr variable during the function execution). The pointer returned is then assigned to the generic variable, overwriting the value stored there by a previous instruction. Consequently you loose an access to the first allocated structure.
EDIT
I'm afraid I do not quite understand what you're trying to achieve. If you want two pointers to the same structure, just declarega1 and assign it a pointer to the created structure:
struct generic_attribute *ga1 = construct_generic_attribute(args[0]);
then make a copy of the pointer:
struct generic_attribute *ga2 = ga1;
I am new to C, and I am facing this problem when practicing.
The struct:
typedef struct {
char name[20];
int score[3];
int no;
} Student;
The initialize:
Student *pStudent;
strcpy(pStudent->name,"Kven");
pStudent->score[0]=1;
pStudent->score[1]=2;
pStudent->score[2]=3;
pStudent->no=1;
If the "pStudent" is not a pointer I can get it right. But if it is a pointer, I will always get a "bad access" error. How to solve it if I must use a pointer? Thank you.
A variable of type pointer stores the address in memory of another variable (it points to another variable).
Your variable pStudent is not initialized. It doesn't point to anything. In fact, it contains some garbage value that, most of the times, is the address of a memory area where the program is not allowed to write. This is why when you attempt to write there (the call to strcpy()) the operating system slaps your program over its "hand" and terminates it with the error message you mentioned.
How to correctly use pointers
One usage of pointers is to point to a certain variable that is statically allocated (defined in the program):
Student s, *pStudent = &s;
This example declares the variable s of type Student and the variable pStudent that points to it. Notice it is initialized with &s which is the address of s. Now, your code uses pStudent to initialize the fields of s.
Another usage of pointers is to dynamically allocate memory during runtime:
Student *pStudent;
pStudent = malloc(sizeof(Student));
In this situation, pStudent is initialized with the address of a new variable of type Student that is created during runtime (it doesn't have a name) by calling malloc(). malloc() allocates a block of memory (of the specified size) and return its address.
When you don't need it, you have to free the memory allocated by malloc() (using free()) for reuse:
free(pStudent);
After this call, the value of the variable pStudent doesn't change, it still points to the same address but it is invalid and using it produces undefined behaviour. You have to put the address of another Student structure in pStudent (using one of the two ways presented here) before using it again.
Student *pStudent;
should be
Student *pStudent = malloc(sizeof(Student));
Allocate memory for the pointer before writing data once done using it
free(pStudent);
Student *pStudent;
creates a pointer of type Student*. This pointer is not initialized and points to some "random" location. Allocate memory for it using malloc(or calloc) from stdlib.h:
pStudent = malloc(sizeof(Student));
and then free it after its use using:
free(pStudent);
You don't allocate any memory, you just allocate a pointer. You'll need to study pointers and how they work.
Fix the code like this:
Student student;
strcpy(student.name,"Kven");
student.score[0]=1;
student.score[1]=2;
student.score[2]=3;
student.no=1;
Alternatively you could allocate memory dynamically. But it doesn't make any sense in this case (and yet I bet at least 3 people will post answers telling you to do that...). Plus you really need to study pointers before doing dynamic allocation.
Student *pStudent = calloc(1, sizeof(Student);
if(pStudent == NULL)
{
// error handling
}
strcpy(pStudent->name,"Kven");
pStudent->score[0]=1;
pStudent->score[1]=2;
pStudent->score[2]=3;
pStudent->no=1;
...
free(pStudent);
You need to allocate memory for your structure first.
You can allocate memory with:
Student *pStudent = malloc(sizeof(Student));
And then you must release it at the end with
free(pStudent);
Let's say I have this struct
typedef struct person{
char firstName[100], surName[51]
} PERSON;
and I am allocating space by malloc and filling it with some values
PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));
strcpy(testPerson->firstName, "Jack");
strcpy(testPerson->surName, "Daniels");
What is the correct and safe way to free all memory taken by that struct? Is "free(testPerson);" enough or do I need to free each struct's attribute one by one?
It leads me to another question - how are structures stored in memory? I noticed a strange behaviour - when I try to print structure address it's equal to it's first attribute's address.
printf("Structure address %d == firstName address %d", testPerson, testPerson->firstName);
Which means that this
free(testPerson)
should be equal to this
free(testPerson->firstName);
and that's not what I want to do.
Thanks
Simple answer : free(testPerson) is enough .
Remember you can use free() only when you have allocated memory using malloc, calloc or realloc.
In your case you have only malloced memory for testPerson so freeing that is sufficient.
If you have used char * firstname , *last surName then in that case to store name you must have allocated the memory and that's why you had to free each member individually.
Here is also a point it should be in the reverse order; that means, the memory allocated for elements is done later so free() it first then free the pointer to object.
Freeing each element you can see the demo shown below:
typedef struct Person
{
char * firstname , *last surName;
}Person;
Person *ptrobj =malloc(sizeof(Person)); // memory allocation for struct
ptrobj->firstname = malloc(n); // memory allocation for firstname
ptrobj->surName = malloc(m); // memory allocation for surName
.
. // do whatever you want
free(ptrobj->surName);
free(ptrobj->firstname);
free(ptrobj);
The reason behind this is, if you free the ptrobj first, then there will be memory leaked which is the memory allocated by firstname and suName pointers.
First you should know, how much memory is allocated when you define and allocate memory in below case.
typedef struct person{
char firstName[100], surName[51]
} PERSON;
PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));
1) The sizeof(PERSON) now returns 151 bytes (Doesn't include padding)
2) The memory of 151 bytes is allocated in heap.
3) To free, call free(testPerson).
but If you declare your structure as
typedef struct person{
char *firstName, *surName;
} PERSON;
PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));
then
1) The sizeof(PERSON) now returns 8 bytes (Doesn't include padding)
2) Need to allocate memory for firstName and surName by calling malloc() or calloc(). like
testPerson->firstName = (char *)malloc(100);
3) To free, first free the members in the struct than free the struct. i.e,
free(testPerson->firstName);
free(testPerson->surName);
free(testPerson);
free is not enough, free just marks the memory as unused, the struct data will be there until overwriting. For safety, set the pointer to NULL after free.
Ex:
if (testPerson) {
free(testPerson);
testPerson = NULL;
}
struct is similar like an array, it is a block of memory. You can access to struct member via its offset. The first struct's member is placed at offset 0 so the address of first struct's member is same as the address of struct.
Because you defined the struct as consisting of char arrays, the two strings are the structure and freeing the struct is sufficient, nor is there a way to free the struct but keep the arrays. For that case you would want to do something like struct { char *firstName, *lastName; }, but then you need to allocate memory for the names separately and handle the question of when to free that memory.
Aside: Is there a reason you want to keep the names after the struct has been freed?
This way you only need to free the structure because the fields are arrays with static sizes which will be allocated as part of the structure. This is also the reason that the addresses you see match: the array is the first thing in that structure. If you declared the fields as char * you would have to manually malloc and free them as well.
Mallocs and frees need to be paired up.
malloc grabbed a chunk of memory big enough for Person.
When you free you tell malloc the piece of memory starting "here" is no longer needed, it knows how much it allocated and frees it.
Whether you call
free(testPerson)
or
free(testPerson->firstName)
all that free() actually receives is an address, the same address, it can't tell which you called. Your code is much clearer if you use free(testPerson) though - it clearly matches up the with malloc.
You can't free types that aren't dynamically allocated. Although arrays are syntactically similar (int* x = malloc(sizeof(int) * 4) can be used in the same way that int x[4] is), calling free(firstName) would likely cause an error for the latter.
For example, take this code:
int x;
free(&x);
free() is a function which takes in a pointer. &x is a pointer. This code may compile, even though it simply won't work.
If we pretend that all memory is allocated in the same way, x is "allocated" at the definition, "freed" at the second line, and then "freed" again after the end of the scope. You can't free the same resource twice; it'll give you an error.
This isn't even mentioning the fact that for certain reasons, you may be unable to free the memory at x without closing the program.
tl;dr: Just free the struct and you'll be fine. Don't call free on arrays; only call it on dynamically allocated memory.