Issue regarding memory allocation in C - c

For some reason, I cannot manage to correctly free the structure I created, which goes as follows:
struct dictionary{
char word[50]; // Word to be described
char definition[150]; // Definition of said word
struct dictionary* next; // Linked list structure
}*dic;
typedef struct dictionary Dic;
Dic* newWord(char word[], char definition[]){
Dic* dc;
dc = malloc(sizeof(*dic));
strcpy(dc->word,word);
strcpy(dc->definition,definition);
dc->next = NULL;
return dc;
}
Now, if I do something like:
dc = newWord("Word","definition");
free(dc);
printWord(dc);
where:
void printWord(Dic* dic){
if(dic){
printf("<%s>\n",dic->word);
printf(".%s\n",dic->definition);
}
}
will result in no word being printed, yet the definition still being printed, which I can only assume means I'm not properly freeing this structure's memory. How do I go by properly doing it?

You are using a pointer after freeing it. This is undefined behavior, which means the C compiler can do whatever it wants. It can crash, it can appear to behave properly, or it can do anything in between. Calling free on a pointer doesn't set it to NULL, it releases your claim on the memory, but you have to set it to NULL yourself.

Related

double linked list in c send data from function

This is my code:-
typedef struct Frame
{
char* name;
unsigned int duration;
char* path; // may need to scan (with fgets)
}frame_t;
typedef struct Link
{
frame_t* frame;
struct Link* next;
}link_t;
void addNewFrame(void)
{
link_t* newLink = (link_t**)malloc(sizeof(link_t*));
printf(" *** Creating new frame ***\n\n");
printf("Please insert frame path:\n");
// newLink->frame->name = (char*)malloc(sizeof(char) * MAX_LEN);
fgets(newLink->frame->name, MAX_LEN,stdin);
printf("%s", newLink->frame->name);
}
I just need to add a data to name variable in the "Frame" link list, please help me by reviewing this code.
You want to allocate the right types here:-
link_t* newLink = malloc(sizeof(link_t)); //Pointer to Link st
if(newLink){
newLink->frame = malloc(sizeof(frame_t)); //Pointer to frame member
if(newLink->frame){
newLink->frame->name = malloc(sizeof(char) * MAX_LEN); //Pointer to name member
if(newLink->frame->name){
//Rest of your code
}
}
}
EDIT:-
1. As pointed out in comments there's no need to cast the pointer returned by malloc()
2. Another very imp point you may want to check validity of the pointers before de-referencing them
First. You don't need to cast void * so (link_t **)malloc(... can be only malloc(....
Second. You allocated enough memory for a pointer not for a struct. I think you mean malloc(sizeof(link_t)) or even better malloc(sizeof(*newLink))
Third newLink->frame is a pointer so you need to allocate data for it too, newLink->frame = malloc(sizeof(frame_t))
Fourth newLink->frame->name is still a pointer so you need to allocate data for it too. newLink->frame->name = malloc(MAX_LEN)
The confusion that you are doing is pretty common. When you say type *something you are allocating a pointer to type in the stack. A pointer needs to point to somewhere else or NULL, or bad things happen. This applies to structures too. If your structure has a pointer member you need to point it to somewhere else. The somewhere else is where the real "type" object resides.
This also applies to arrays. If you say 'int foo[10]' you are allocating ten integers in the stack. If you say int *foo[10] you are allocating ten pointers in the stack. If you say int **foo you are allocating one pointer in the stack. Again all pointers need to be initialized, I mean, they need to point to some valid object, allocated somewhere else in the memory.
I hope this helps.
Some other points.
Always check pointer coming from malloc, if allocation failed you'll receive NULL. Dereferencing NULL will break your program.
Always initialize memory coming from malloc, fill it with zeros or something.
Don't use _t suffix, is POSIX reserved.
I didn't test any of this.

Cannot figure out how to free my structure

I need to free() all the memory allocated for my structure config.
struct keysnvalues {
char* key;
char* value;
};
struct section {
char *name;
struct keysnvalues *keysnvalues;
int keysnvalues_ammount;
};
struct config {
struct section *sections;
int section_ammount;
};
In the beggining of the code I do this
struct section * sect = malloc(sizeof(struct section) * 255);
struct keysnvalues * keysnvalue = malloc(sizeof(struct keysnvalues) * 255);
If I want to add section I do this for the first one
sect[++num_section].name = buffer; // buffer is the name
And for the next sections
sect[num_section].keysnvalues = keysnvalue;
sect[num_section].keysnvalues_ammount = num_keysnvalues;
cfg -> section_ammount++;
//start with new keysnvalue
num_keysnvalues = 0;
keysnvalue = malloc(sizeof(struct keysnvalues) * 255);
sect[++num_section].name = buffer;
sect[num_section].keysnvalues = 0;
If I want to add a key and a value to section I am working with I do this
keysnvalue[num_keysnvalues].key = key;
keysnvalue[num_keysnvalues++].value = value;
The whole code is here: https://pastebin.com/pGztJ9k4
I am aware of the fact that this is probably a stupid question, but I could not figure out how to free the whole structure config for hours now.
I would really appreciate your help.
Generally, you should free() a pointer if and only if it has been allocated through malloc(). To achieve this, you have to make sure not to "loose" any pointer to a malloced memory address, e.g. by assigning malloc several times to the same variable without having copied it's previous value or without having freed the previously assigned memory.
I did not analyse the complete code you referred to.
But it seems as if you copy the value of keysnvalue to the current section before mallocing a new value for sect[i].keysnvalues.
Hence, it seems that each section get's its own keysnvalue, and you can loop it through:
for (int i=0;i< num_section;i++) {
if (sect[i].keysnvalues != NULL) {
free(sect[i].keysnvalues);
// free(sect[i].name); // if buffer has also been malloced
}
}
free (keysnvalue);
free (sect);
It may be that you also have to loop trough each sect[i].keysnvalue in order to eventually free key/value.
Make sure that section members that you are going to free at the end of the program are always initialised either with NULL or a malloced value in order to prevent your code from "freeing" a garbage pointer value.
When you reset 'keysnvalue' with the next 'malloc()', you are overwriting the pointer to the previous value of 'keysnvalue'. That leaves the associated storage unreachable, i.e a 'memory leak' [unless you maintain a copy of the previous value of 'keysnvalue' in another location]. If you are really replacing the structure with a fresh one, you must 'free()' the old one first, AND THEN 'malloc()' the next one - you cannot wait until the end to clean up everything.
Personally I wouldn't do it that way - for a fresh structure, I would call 'memset()' to zero out the existing structure.

Need to check if struct has been initialized

Hi I am making a Queue abstact data type and I ran into a problem which I will try to explain as clearly as possible.
Basically I have a two structs one for an element and one for a queue (so you can initialize multiple queues).
struct element
{
TYPE value;
struct element* next;
};
struct queue
{
struct element* head;
struct element* tail;
int element_counter;
};
And I have a function which initializes my queue struct.
int make_new_queue(struct queue* name)
{
name = malloc(sizeof(struct queue));
name->head = NULL;
name->tail = NULL;
name->element_counter = 0;
}
The problem I ran into is foolproofing this code. For example I initialised my first queue in my main function.
struct queue* first = make_new_queue(first);
But if somebody tries to do the same thing again somewhere in the middle of the code write:
first = make_new_queue(first);
it overrides it and makes the head and tail pointers NULL. The thing I can't figure out is how to make my make_new_queue function better and check if there is something in the queue that I provide it, but still let me initialise empty queues.
Sorry for my english. I hope you get the idea of what I want to do. Thanks.
Initialize it to NULL and pass a pointer to pointer:
void make_new_queue(struct queue **name)
{
if (*name != NULL) return; /* Yet initialized ? */
*name = malloc(sizeof(struct queue));
if (*name == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
*name->head = NULL;
*name->tail = NULL;
*name->element_counter = 0;
}
struct queue *first = NULL;
make_new_queue(&first);
You can simply check if you variable name is NULL.
If your variable is non-null, you can alloc and initialize your queue else just do what you want to do.
There is really no good way to enforce what you want without discipline from the user. In my opinion, the best approach is to stick to known patterns.
You can use Alter Mann's approach to pass a pointer to a pointer to update the struct. The drawback is that is that you have to separate variable declaration and initialisation. It also relies on the user to initialise the pointer to the struct to NULL. If you forget it, the queue pointer will not be initialised and you don't even know, because you can't check against NULL.
struct stuff *stuff = NULL;
stuff_initialise(&stuff);
You can use your original approach to pass in the struct and return the same struct when it was initialised or a new one. It has the same problems as the first approach plus the possibility that you forget to assign the return value. You can, however, combine allocation and initialisation:
struct stuff *stuff = stuff_new(NULL);
The simplest way is not to pass the old pointer and rely on the user not to change the pointer after allocation. After all, the functions of the standard library suffer from the same problem:
char *buf = malloc(BUFSIZE);
buf = malloc(2 * BUFSIZE); // Memory leak
buf++; // Allowed, but a bad idea
free(buf); // Ouch!
FILE *f = fopen("palomino.txt", "r");
f = stdin; // Switch horses midstream?
You should design your API so that you have matching pairs of functions that define the scope of your struct:
struct stuff *stuff = stuff_create(...);
// use stuff ...
stuff_destroy(stuff);
Good naming should make clear that stuff acts as a handle and should not be changed and that after closing or destroying the handle, it is invalid. You should see these calls as first and last statements in functions. (This method is similar to the malloc/free or fopen/fclose pairngs of the standard library.)
Finally, if you as the user of a handle want to avoid accidential changes, you can define the pointer (not what it points to) as const:
struct stuff *const handle = stuff_create("X");
handle = stuff_create("Y"); // Compiler error
But I rarely see this. C programmers usually just use an unadorned pointer and remember to keep their fingers off the hotplate.

C generic linked-list

I have a generic linked-list that holds data of type void* I am trying to populate my list with type struct employee, eventually I would like to destruct the object struct employee as well.
Consider this generic linked-list header file (i have tested it with type char*):
struct accListNode //the nodes of a linked-list for any data type
{
void *data; //generic pointer to any data type
struct accListNode *next; //the next node in the list
};
struct accList //a linked-list consisting of accListNodes
{
struct accListNode *head;
struct accListNode *tail;
int size;
};
void accList_allocate(struct accList *theList); //allocate the accList and set to NULL
void appendToEnd(void *data, struct accList *theList); //append data to the end of the accList
void removeData(void *data, struct accList *theList); //removes data from accList
--------------------------------------------------------------------------------------
Consider the employee structure
struct employee
{
char name[20];
float wageRate;
}
Now consider this sample testcase that will be called from main():
void test2()
{
struct accList secondList;
struct employee *emp = Malloc(sizeof(struct employee));
emp->name = "Dan";
emp->wageRate =.5;
struct employee *emp2 = Malloc(sizeof(struct employee));
emp2->name = "Stan";
emp2->wageRate = .3;
accList_allocate(&secondList);
appendToEnd(emp, &secondList);
appendToEnd(emp2, &secondList);
printf("Employee: %s\n", ((struct employee*)secondList.head->data)->name); //cast to type struct employee
printf("Employee2: %s\n", ((struct employee*)secondList.tail->data)->name);
}
Why does the answer that I posted below solve my problem? I believe it has something to do with pointers and memory allocation. The function Malloc() that i use is a custom malloc that checks for NULL being returned.
Here is a link to my entire generic linked list implementation: https://codereview.stackexchange.com/questions/13007/c-linked-list-implementation
The problem is this accList_allocate() and your use of it.
struct accList secondList;
accList_allocate(&secondList);
In the original test2() secondList is memory on the stack. &secondList is a pointer to that memory. When you call accList_allocate() a copy of the pointer is passed in pointing at the stack memory. Malloc() then returns a chunk of memory and assigns it to the copy of the pointer, not the original secondList.
Coming back out, secondList is still pointing at uninitialised memory on the stack so the call to appendToEnd() fails.
The same happens with the answer except secondList just happens to be free of junk. Possibly by chance, possibly by design of the compiler. Either way it is not something you should rely on.
Either:
struct accList *secondList = NULL;
accList_allocate(&secondList);
And change accList_allocate()
accList_allocate(struct accList **theList) {
*theList = Malloc(sizeof(struct accList));
(*theList)->head = NULL;
(*theList)->tail = NULL;
(*theList)->size = 0;
}
OR
struct accList secondList;
accList_initialise(secondList);
With accList_allocate() changed to accList_initialise() because it does not allocate
accList_initialise(struct accList *theList) {
theList->head = NULL;
theList->tail = NULL;
theList->size = 0;
}
I think that your problem is this:
You've allocated secondList on the stack in your original test2 function.
The stack memory is probably dirty, so secondList requires initialization
Your accList_allocate function takes a pointer to the list, but then overwrites it with the Malloc call. This means that the pointer you passed in is never initialized.
When test2 tries to run, it hits a bad pointer (because the memory isn't initialized).
The reason that it works when you allocate it in main is that your C compiler probably zeros the stack when the program starts. When main allocates a variable on the stack, that allocation is persistent (until the program ends), so secondList is actually, and accidentally, properly initialized when you allocate it in main.
Your current accList_allocate doesn't actually initialize the pointer that's been passed in, and the rest of your code will never see the pointer that it allocates with Malloc. To solve your problem, I would create a new function: accList_initialize whose only job is to initialize the list:
void accList_initialize(struct accList* theList)
{
// NO malloc
theList->head = NULL;
theList->tail = NULL;
theList->size = 0;
}
Use this, instead of accList_allocate in your original test2 function. If you really want to allocate the list on the heap, then you should do so (and not mix it with a struct allocated on the stack). Have accList_allocate return a pointer to the allocated structure:
struct accList* accList_allocate(void)
{
struct accList* theList = Malloc( sizeof(struct accList) );
accList_initialize(theList);
return theList;
}
Two things I see wrong here based on the original code, in the above question,
What you've seen is undefined behaviour and arose from that is the bus error message as you were assigning a string literal to the variable, when in fact you should have been using the strcpy function, you've edited your original code accordinly so.. something to keep in mind in the future :)
The usage of the word Malloc is going to cause confusion, especially in peer-review, the reviewers are going to have a brain fart and say "whoa, what's this, should that not be malloc?" and very likely raise it up. (Basically, do not call custom functions that have similar sounding names as the C standard library functions)
You're not checking for the NULL, what if your souped up version of Malloc failed then emp is going to be NULL! Always check it no matter how trivial or your thinking is "Ah sher the platform has heaps of memory on it, 4GB RAM no problem, will not bother to check for NULL"
Have a look at this question posted elsewhere to explain what is a bus error.
Edit: Using linked list structures, in how the parameters in the function is called is crucial to the understanding of it. Notice the usage of &, meaning take the address of the variable that points to the linked list structure, and passing it by reference, not passing by value which is a copy of the variable. This same rule applies to usage of pointers also in general :)
You've got the parameters slightly out of place in the first code in your question, if you were using double-pointers in the parameter list then yes, using &secondList would have worked.
It may depend on how your Employee structure is designed, but you should note that
strcpy(emp->name, "Dan");
and
emp->name = "Dan";
function differently. In particular, the latter is a likely source of bus errors because you generally cannot write to string literals in this way. Especially if your code has something like
name = "NONE"
or the like.
EDIT: Okay, so with the design of the employee struct, the problem is this:
You can't assign to arrays. The C Standard includes a list of modifiable lvalues and arrays are not one of them.
char name[20];
name = "JAMES" //illegal
strcpy is fine - it just goes to the memory address dereferenced by name[0] and copies "JAMES\0" into the memory there, one byte at a time.

Freeing memory of structure linked list using expiration of function scope

My goal is to run a API call repeatedly and check for memory leaks.
The API takes in integer input and returns a pointer to the first structure in a linked list of structures as output. Each structure may have struct variables of other types.
In the following code i have tried to represent my problem.
The problem is in callApi() function. I need to dispose of the memory occupied by the structure 'output' that the API() returns. Even if i use free(output) here, it will cause a memory leak because since it points to a linked list of nested structures. (source of info : http://en.wikibooks.org/wiki/C_Programming/Memory_management)
Question:
When leaving exiting callApi() call, will the 'output' nested structure expire when control goes out of the function back to main()? Will it free the entire memory occupied? Please suggest a solution to way to solve this memory leak problem.
Can this problem be overcome with C++?
typedef struct{
int dev_size;
char *dev_name;
dev_stat *next_dev;
mem_stat *mem_info;
} dev_stat
typedef struct{
int mem_capacity;
char *mem_name;
} mem_stat
int main()
{
int input;
int return_val;
int callApi(int);
while(1)
{
return_val=callApi(input);
print return_val;
}
}
int callApi(int ip)
{
//Update: Memory allocation is unnecessary as it is done inside the API() call itself
//dev_stat *output=(dev_stat *)calloc(2,sizeof(dev_stat));
int ret_val;
ret_val=API(ip,&output);
free(output);
output=NULL;
return ret_val;
}
The simple answer is, no, the memory will not "expire" when you exit a function.
The API should provide a way to "free" the returned value, if it is a complex structure. If it doesn't, then traversing the structure yourself and freeing it is probably the only way out.
The first question who is the owner of the structures you are going to free.
It might be that the API returns a pointer to its internal structure, which you must not deallocate (because, for example, it may be shared).
It might be as well that your code is responsible for deallocating the structure itself, but not the other structures that your structure points to. This way you need to just free the returned structure and forget about it.
It might be however that your responsibility is to free the whole object tree starting at the returned structure. In that case it's to be expected that the API has some function which properly deallocates the structure with its descendants for you. If not (which is most likely not the case), you have to free all the resources referenced by your structure, recursively.
You should look up at the APi documentation to find out which if the three cases is your case.
Update:
Explicitly for your case (the whole structure should be deallocated manually), I would use something like that:
void free_mem_stat(struct mem_stat* p)
{
if (!p) return;
free(p->mem_name);
free(p);
}
void free_dev_stat(struct dev_stat* p)
{
// first, clean up the leaves
for(struct dev_stat* curr = p; curr; curr = curr->next_dev)
{
free(curr->dev_name);
free_mem_stat(curr->mem_info);
}
// than, clean up the linked list
for(struct dev_stat* curr = p; curr; /**/)
{
struct dev_stat* next = curr->next_dev;
free(curr);
curr = next;
}
}
int callApi(int ip)
{
int ret_val;
struct dev_stat* output;
ret_val = API(ip, &output);
free_dev_stat(output);
return ret_val;
}
Note that the function like free_dev_stat ought to be provided by the API itself, if the API developers really intend to let the users deallocate their structures.

Resources