Usage of strdup() - c

Let's say we have a struct :
struct Person {
char *name;
};
struct Person *Person_create(char *name){
struct Person *who = malloc(sizeof(struct Person));
assert(who != NULL);
who->name = strdup(name);
return who;
}
void Person_destroy(struct Person *who){
assert(who != NULL);
free(who->name);
free(who);
}
And the main function :
int main(int argc,char *argv[]){
struct Person *mike = Person_create("mike");
Person_print(mike);
Person_destroy(mike);
return 0;
}
The above code won't work properly without the strdup() function. Valgrind says that the address you try to free with free(who->name) is not malloc'd. What's the story behind this, didn't I malloc'd that memory when I malloc'd the struct? And what difference does the strdup() make?

In your code each Person object involves two independent blocks of memory: the struct Person object itself and the separate memory block for the name. That separate memory block is pointed by the name pointer inside the struct. When you allocate struct Person by using malloc, you are not allocating any memory for the name. It is, again, an independent block of memory that should be allocated independently.
How you are planning to allocate memory for the name is entirely up to you. If you use strdup (which is essentially a wrapper for malloc) as in your code above, then you will have to free it by free in the end.
You did not explain what you mean by "without the strdup() function". What did you code look like without it? If you simply did
who->name = name;
then you made that who->name pointer to point directly to the string literal memory occupied by literal "mike". String literals reside in static memory. You are not allowed to free them. This is what valgrind is telling you.

Mallocing the struct allocates memory for the pointer name but it doesn't allocate any memory for name to point to. At that point who->name will be some random garbage value so freeing it makes no sense.
strdup uses malloc internally to allocate memory for the string it copies. Once you've got a pointer back from strdup you can, and should, free it when you're done.

strdup do noes call malloc, it is only string operation. you only malloc the pointer to the struct ,not the inner member

Related

Does malloc assigns memory to custom struct's properties?

I've been working on some C projects and was wondering if I create a custom structure, for example, Student, define a variable of the custom structure type, and allocate memory to it using malloc, does it also allocate memory for variables' properties separately or are they all kept in the same space? if yes, will there be any difference if I allocate memory using malloc separately for every property?
For example:
typedef struct {
unsigned int ID;
char *first_name;
char *last_name;
int num_grades;
float *grades;
unsigned short int days_absent;
char *memo;
} Student;
int main() {
// Declare students array
Student *students = NULL;
int students_size = 0;
// Allocate memory for students array
students = (Student *) malloc(sizeof(Student));
return 0;
}
That allocates enough memory for the struct, which includes enough memory for ID, first_name, etc and all padding requirements.
Note that while it allocates memory for the pointer first_name, it doesn't allocate a buffer to hold the name. It just allocates memory for first_name, a pointer. If you want memory in which to store the names, you will need to allocate it.
If the struct had a char first_name[40]; field, it would be a different story. To allocate enough memory for first_name, it needs to allocate enough memory for an array of 40 char instead of enough for a pointer. This does provide a space in which a string could be stored.
No, it doesn't. It allocates uninitialized memory for the number of chars you want - which is usually a calculation based on sizeofs.
If you want it to allocate memory to store values that your struct has pointers to, you'll have to add that after having allocated the memory for the struct.
You'll also have to "go backwards" when you free such a struct.
Example:
typedef struct {
char *data;
} foo;
foo *foo_create() {
foo *retval = malloc(sizeof *retval ); // try allocation
if(retval == NULL) return NULL; // check that it worked
retval->data = malloc(10) ; // allocate something for a member
if(retval->data == NULL) { // check that it worked
free(retval); // oh, it didn't, free what you allocated
return NULL; // and return something to indicate failure
}
return retval; // all successful
}
void foo_free(foo *elem) {
if(elem != NULL) { // just a precaution
free(elem->data); // free the member's memory
free(elem); // then the memory for the object
}
}
Does it also allocate memory for variables' properties separately
No. After allocating for students, allocate for students->first_name, students->last_name, etc.
does it also allocate memory for variables' properties separately or are they all kept in the same space?
No. malloc() is given a size to indicate how much contiguous memory to allocate, and it returns a pointer pointing to it... malloc() knows nothing about what you are going to do with the pointer. When you assign it to a pointer variable to Student type is, somehow, dressing a bunch of memory with structure. But the char * fields that you have defined inside (or if you have other fields pointing to other structured data) those have to be allocated separately (or ask for more memory to allocate them all in the same returned segment, but this requires practice and knowledge of the alignment issues that arise from it)

What is the difference between stack struct vs heap struct?

// Define Person
typedef struct Person {
char *name;
int age;
} person_t;
// Init person in heap
person_t *create_person_v1(char *name, int age)
{
person_t *person = calloc(1, sizeof(person_t));
person->name = name;
person->age = age;
return person;
}
// Init person on stak? a static struct I guess?
person_t create_person_v2(char *name, int age)
{
return (person_t) {name, age};
}
The code above has a definition of Person and two helper functions for its further initialization.
I don't really understand the difference between them, and what are the benefits of having each?
Is it something more than just accessors -> and . ?
The last function does not allocate a static structure, but a structure on the stack. There is two kind of memory for your programm, heap and stack. static is an other keyword (which have more than 1 use, depending on where they are used, but it's not the current subject).
heap allocations use more ressources than stack allocations, but are not tied to scopes where they are used. You can manipulate structures heap allocated between functions without having to think they can be "automatically freed" because the scope on which they are tied disappear (aka : initial function returned).
An example would be a linked list. You can't rely on stack allocations to build a linked list of structures.
Heap allocations can fail, you always have to check if malloc, calloc and cie, does not return NULL.
Stack allocations doesn't fail like that. If you sucked all your stack, your programm will just crash. ( Or do some fancy things, it is undefined bahavior ). But you can't recover from that.
stack allocated memory is "freed" on function returns.
not heap allocated memory. But you have to free it by hand (with function free)

C - What is wrong with my memory freeing function?

I have a struct which contains 2 integers and a pointer to another struct. I allocate memory for struct first and then for the pointer. When I free the memory I free up the pointer first and then I free up the struct.
When I run my program and call the function that frees memory it crashes when the call is made. When I don't call the function that frees memory it works fine, but then I'm not freeing up the memory.
I tried removing the line that frees the memory allocated to the pointer and the program doesn't crash, but I don't think thats right since a "free" is needed for every "malloc/calloc" right? Anyone see anything wrong with the freeing function?
//Define a struct data type
struct q_element
{
//Declaration of struct members
int element;
int priority;
struct q_element *next_element;
};
//Method to allocate memory
struct q_element* allocateStruct()
{
//Declaration of a variable
struct q_element *e;
//Allocate memory for one queue element
e = malloc(sizeof(struct q_element));
//Allocate memory for one pointer to a queue element
e->next_element = calloc(1,sizeof(struct q_element*));
//Initialize integer members of queue element
e->element = 0;
e->priority = 0;
return e;
}
//Method to free memory allocated
void freeStruct(struct q_element* e)
{
//Free up pointer member
free(e->next_element);
//Free up struct
free(e);
}
You don't need to allocate memory for the next_element pointer. The pointer is already there, just like int element for example.
So if you want to allocate just one element, you can set the next_element pointer to NULL and everything is fine.
You are not allocating enough memory for e->next_element in the line:
e->next_element = calloc(1,sizeof(struct q_element*));
// ^^^ remove the *
That should be:
e->next_element = calloc(1,sizeof(struct q_element));
If you used e->next_element as though it were a valid pointer, you most likely ended up accessing memory that you did not allocate. That clobbered some of the bookkeeping information created by calloc, which lead to problems when you called free.
In
//Allocate memory for one pointer to a queue element
e->next_element = calloc(1,sizeof(struct q_element*));
you allocate space for a pointer to a q_element structure, rather than a q_element structure. Do you attempt to write to this structure, because if so, that's probably where it goes wrong.
As a side note you might be better off just doing
e->next_element = 0
inside allocate_struct and then doing e->next_element = allocate_struct() outside the function later.
In addition to what everyone else is mentioning about allocation, you also need a sentinel to check if the next_element was already freed. You may be attempting a double free.
Try the following code:
void freeStruct(struct q_element* e)
{
//Free up pointer member
if(e->next_element != 0){
free(e->next_element);
e->next_element = 0;
}
//Free up struct
free(e);
}

Confused by malloc and free behaviour

I am confused with the usage of free() in regard to data structures in C.
If I have the following data structure:
struct Person {
char *name;
int age;
float weight;
float height;
};
I am allocating memory for the structure via malloc(), likewise: struct Person *me = malloc(sizeof(struct Person));
After I am done with using my structure (right before ending the program), I proceed to freeing the memory allocated, like this:
free(person_pointer->name);
free(person_pointer);
Freeing the memory that the name pointer points to is necessary to my knowledge, because if I only free person_pointer I only free the memory that was allocated to store the data structure and its members but not the memory that is pointed to by pointers-members of the structure.
However with my implementation valgrind seems to suggest that the first free() is invalid.
So my question boils down to: When I free the memory that a struct occupies via a pointer, should I preemptively free the memory that member pointers point to or not?
EDIT: This is my whole code:
#include <stdio.h>
#include <stdlib.h>
struct Person {
char *name;
int age;
float weight;
float height;
};
int main(int argc, char **argv)
{
struct Person *me = malloc(sizeof(struct Person));
me->name = "Fotis";
me->age = 20;
me->height = 1.75;
me->weight = 75;
printf("My name is %s and I am %d years old.\n", me->name, me->age);
printf("I am %f meters tall and I weight %f kgs\n", me->height, me->weight);
free(me->name);
free(me);
return 0;
}
me->name = "Fotis";
/* ... */
free(me->name);
The rule is:
1 malloc = 1 free
You didn't use malloc on me->name, so you don't have to free it.
BTW, me->name should be of const char * type.
When you do
me->name = "Fotis";
The name pointer is not alloced by malloc, it points to a stack variable which is stored in the strings table of your binary file at compile time, hence you can't free it.
The rule of thumb is : Only free what you have malloced.
You can't update this read-only string though.
If you did something like :
me->name = strdup("Fotis");
Since strdup does a malloc (see the manual), you have to free it, and you can update the string after its creation.
Yes you have to free all the memory of pointers inside the structure if you allocated them.
Also make sure you free the members before you free the structure.
A simple way to remember is free them in the reverse order in which you have allocated.
The problem is that you didn't actually malloc'ed the char * name inside your structure.
struct Person *me = malloc(sizeof(struct Person));
me->name = strdup("Fotis");
...
free(me->name);
free(me);
return (0);
When you write this
me->name = "Fotis";
You don't actually malloc, the pointer name points to a stack variable of type const char *, wich is not malloc'ed.

Freeing struct with pointer and non-pointer variables

I'm trying to implement linked-lists with c struct, I use malloc to allocate a new node then allocate space for value, so I've been thinking how to free the structure once I'm done with them, my structure looks like this:
typedef struct llist {
char *value;
int line;
struct llist *next;
} List;
I have a function that walks through the struct and free its members like this:
free(s->value);
free(s);
My question is, does that also free the int line?
Yes.
The int line is part of the structure, and so gets freed when you free the structure. The same is true of the char *value. However, this does not free the memory which value points at, which is why you need to call free separately for that.
Yes it does. When you allocated memory for s it allocated memory for these three:
pointer to a char (value)
integer (line)
pointer to a struct llist (next)
When you freed s, all that storage went away (which includes memory for line).

Resources