memory free throws segFault - c

I am implementing symbol table using link list, The code works fine but there is memory leak in code,
I have following structure
struct node
{
char* pcKey;
void* pvValue;
struct node *next;
};
struct _Sym
{
int totalBindings;
struct node *node;
};
add I have sym_new method to allocate memory for sym instance
sym Sym_new (void)
{
_Sym *m_SymTable_t = (_Sym*) malloc (sizeof(_Sym));
if(m_SymTable_t == NULL)
{
return NULL;
}
else
{
m_SymTable_t->totalBindings = 0;
m_SymTable_t->node = NULL;
return m_SymTable_t;
}//endif
}
I am allocating memory for key and value in other function based on the string length.
The free method is
typedef struct _Sym *Sym;
void Sym_free (Sym m_SymTable_t)
{
assert(m_SymTable_t != NULL);
struct node* temp = m_SymTable_t->node;
struct node *currentBinding = NULL;
while(temp != NULL)
{
currentBinding = temp;
temp = temp -> next;
//Removing comment for the below line throws segfault
//free(currentBinding -> pcKey);
//free(currentBinding -> pvValue);
free(currentBinding);
}
free(m_SymTable_t);
}
What is proper way to free the sym completely?
I have uploaded my symTable_Link.cpp file at link

The variables pcKey and pvValue should probably be initialised to null in the Sym_new() function. Otherwise they may contain any old value. This is because malloc doesn't necessarily zero the memory allocated: it just allocates a chunk of memory and the memory could therefore be filled with junk.
So, if for some reason sym_put() is not called for the newly created object these pointers could point to invalid memory and upon your call to free() segfault. If you initialise them to null free() will just ignore them and won't try to free the memory.
A "hacky" DEBUG-only technique you could use to check that the pcKey and pvValue variables are definitely allocated by a sym_put call would be to initialise them in sym_new with a dummy value, for example 0xCDCDCDCD (careful about pointer-widths here... this is why I'm calling this a hacky technique). Then in sym_free check for this magic constant before freeing pcKey and pvValue. If you find it, there's the problem...
Also of interest may be the thread Do I cast the result of malloc?
EDIT:
Looked at the code linked and you appear to be discarding const!
The function id defined as:
int SymTable_put (SymTable_t m_SymTable_t, const char *pcKey, const void *pvValue)
But then does this cast...
temp->pcKey = (char*)pcKey;
temp->pvValue = (char*)pvValue;
This is a bad idea. You're "fooling" the compiler into invalidating your const promise.
THE BUG:
Ok, so you allocate as follows
temp->pcKey = (char*) malloc (sizeof(char) * strlen (pcKey));
But then you overwrite this pointer using
temp->pcKey = (char*)pcKey;
So you a) have a memory leak and b) have just stashed the wrong pointer, which is probs why you get the segfault. You you probably meant to do instead is (strdup is useful here)...
temp->pcKey = strdup(pcKey);
This will allocate new memory for the string in pcKey and COPY the string into the new memory.
I would hazzard a guess you called the function like this...
SymTable_put (xxx, "KEY string", "VALUE string");
Then your code did this
temp->pcKey = (char*)malloc (sizeof(char) * strlen (pcKey));
...
temp->pcKey = (char*)pcKey;
So now temp->pcKey points to "KEY string" itself and not a copy of it. So when you try to free the string constant, your program complains. What you want to do is copy the string from pcKey into temp->pcKey instead of overwriting the pointer.
EDIT:
As per comments the mallocs need space + 1 to include the null terminator. Also sizeof(char) is always 1, so is redundant. Try strdup instread.

Related

C11 - Realloc on array of structs fails when doing realloc twice

I'm trying to use malloc and realloc to hold an array of structs. The array should dynamically grow, size should increase by 10 struct elements every time.
Struct:
typedef struct
{
unsigned char foreign_word_[100] = {0};
unsigned char native_word_[100] = {0};
} VocabularyCouple;
In my main, I initialize the array with malloc:
VocabularyCouple* VocStruct = (VocabularyCouple*)malloc(sizeof(*VocStruct) * 10);
Increasing the size of the struct-array seems to work fine in main...
VocabularyCouple* temp = (VocabularyCouple*)realloc(VocStruct, (sizeof(VocabularyCouple) * 20));
if (temp == NULL)
{
printf("ERROR: Out of Memory\n");
return 4;
}
else
{
VocStruct = temp;
free(temp);
temp = NULL;
}
However, if I put the realloc-part into a function like this:
uint8_t resizeVoc(uint32_t new_size, VocabularyCouple **VocStruct)
{
VocabularyCouple *temp = (VocabularyCouple*)realloc(*VocStruct, (sizeof(VocabularyCouple) * new_size));
...
}
I can only call the function once. Every other call will result in this error:
HEAP[VocTest.exe]: Invalid address specified to RtlValidateHeap( 01300000, 01308500 )
Unless I'm missing something, this should be the same problem as c - Realloc an array of Structs, but I just can't get it to work.
Thank you for your help!
VocStruct = temp;
free(temp);
This is wrong, you free all memory as soon as you have allocated it. VocStruct and temp point at the same memory area. Just remove the free().
To clarify, the temp pointer is just there in case realloc fails. Had you written VocStruct = realloc(VocStruct, ... and realloc fails, then you would have overwritten the only pointer to the allocated memory with NULL and created a memory leak. But you only ever have 1 chunk of memory - even though 2 pointers point at it at the same time.

realloc strange memory leak

I have a n-ary tree:
struct node {
char *data;
int numofkids;
struct node **kids;
}
and a function:
addToParent(struct node *parent, struct node *kid);
that attaches a kid to a parent.
I do that by reallocing the kids array of the father every time I want to add a new kid.
The body:
parent->numofkids ++;
parent->kids = realloc(parent->kids, parent->numofkids * sizeof(char *));
parent->kids[(parent->numofkids) - 1] = kid;
I run my program using valgrind --leak-check=yes ./myprog and it shows memory leaks from realloc function of addToParent function. That means I have to free() something? But what? I am not removing kids, I am just adding the given kid to the given parent.
Valgrind:
The right way to use realloc() is
struct node * temp = realloc(parent->kids, parent->numofkids * sizeof(char *));
if(temp != NULL)
parent->kids = temp;
else
{
/* take necessary action when allocation fails */
}
Because realloc() can fail and if it fails you will end up losing the original data before the realloc() call. Once done using the memory you need to free() it.
There is actually a bunch of potential problems in that code, or in the code calling it (which you haven't shown).
Firstly, the size allocated should be in related to the size of the object being allocated. Not to a multiple of sizeof(char *).
Second, realloc() returns NULL if it fails, and that should be checked for, rather than assuming it succeeds.
Based on these, you need to do something like this
struct node **temp = realloc(parent->kids, (parent->numofkids+1)*sizeof(*temp));
if (temp != NULL)
{
parent->kids = temp;
++parent->numofkids;
parent->kids[parent->numofkids - 1] = kid;
}
else
{
/* reallocation failed, so leave the pointers alone and complain bitterly */
}
The other things to check;
Since you're passing in a pointer to a struct node, check whether the object being passed is valid (e.g. it is not an uninitialised pointer) and that it is being released by the caller when done.
Check that parent points at something value before the first call of your function, and that it is released before the program ends.
Check that ALL of the things you've dynamically allocated (or reallocated) are actually released before the program ends.

How would I free a pointer malloc'd in a separate function?

I have a global variable called exam which is of type struct Exam:
typedef struct
{
Question* phead;
}Exam;
Exam exam;
In a function I malloc space for the pointer phead:
int initExam()
{
exam.phead = malloc(sizeof(Question*));
exam.phead = NULL;
return 1;
}
In a separate function I try to free this memory:
void CleanUp()
{
unsigned int i = 0;
Question* currentQuestion = exam.phead;
while (currentQuestion != NULL) {
// some other code
}
exam.phead = NULL;
}
I have also tried the following inside my function:
free(exam.phead);
My issue is it does not seem to free the memory allocated by malloc. I would like CleanUp() to free up the memory allocated by exam.phead and I cannot change the function signatures or move the free() calls to another function. Is there something I'm doing wrong? I'm fairly new to C programming. Thanks!
You have a memory leak, right from the off:
int initExam()
{
exam.phead = malloc(sizeof(Question*));//assign address of allocated memory
exam.phead = NULL;//reassign member, to a NULL-pointer
return 1;
}
the exam.phead member is assigned the address of the memory you allocated, only to become a null-pointer right after. A null pointer can be free'd safely, but it doesn't do anything.
Meanwhile, the malloc'ed memory will stay allocated, but you have no pointer to it, and therefore cannot manage it. You can't free the memory, nor can you use it. I take it the NULL assignment is an attempt to initialize the memory to a "clean" value. There are ways to to this, which I'll get to in a moment.
Anyway, because phead is NULL, the following statements:
Question* currentQuestion = exam.phead;//is the same as currentQuestion = NULL;
while (currentQuestion != NULL) //is the same as while(0)
don't make sense, at all.
To initialize newly allocated memory, either use memset, or calloc. The latter initializes the allocated block of memory to zero, memset can do this do (calloc is basically the same as calling malloc + memset), but allows you to initialize to any value you like:
char *foo = calloc(100, sizeof *foo);// or calloc(100, 1);
//is the same as writing:
char *bar = malloc(100);
memset(bar, '\0', 100);
You're setting exam.phead in initExam to NULL right after you allocate memory with malloc. free() doesn't do anything with a NULL pointer so you're leaking memory.

invalid realloc/realloc returns NULL

In one function I used malloc :
void name1(struct stos* s)
{
s = malloc (4 * sizeof (int));
}
And everything is ok. But later I used realloc
void name2(struct stos* s)
{
s->size = 2*(s->size);
s = realloc (s, (s->size + 1) * sizeof (int));
}
and I get invalid free/delete/realloc in valgrind and realloc returns NULL.
Declaration of Structure and rest of program is:
struct stos
{
int top;
int size;
int stk[];
};
void name1(struct stos* s);
void name2(struct stos* s);
int main()
{
struct stos stosik;
struct stos* s;
s = &stosik;
name1(s);
//some operations on the array and int top here
name2(s);
}
What did I do wrong here? I looked for what might have gone wrong for quite long, read quite a few articles about pointers, malloc/realloc etc. but with no result. I would be really grateful, if someone could help me.
The problem is slightly subtle and caused by a combination of two things. Let's start here:
struct stos stosik;
struct stos* s;
s = &stosik;
name1(s);
First, you make s point to an a valid chunk of memory that is allocated on the stack (stosik) and then you call name1 passing into s. Let's look at what name1 looks like:
void name1(struct stos* s)
{
s = malloc (4 * sizeof (int));
}
Hmm, we can see that name1 takes in a pointer to a struct stos called s; inside that function, we are allocating some memory and making s point to it. This is a problem.
First of all, note that s already points to a valid chunk of memory. So using a malloc here is suspicious. It will cause a subtle bug that will actually hide the real bug in your program, which is bad. So, let's remove stosik completely:
int main()
{
struct stos* s = NULL;
name1(s);
if(s == NULL)
return -1;
Now, if you run this program, you will see that after you call name1 the variable s still points to NULL. What's happening here?
Well, we are changing the function's LOCAL copy of s (i.e. the s that exists only inside name1)... but the s in main isn't changed! Remember, that we are passing a pointer into name1 but we are passing it by value.
To do what you seem to be trying to do you can do you would have to either pass a pointer to s into name1 (that is, to pass a double pointer) or you should return the result of the malloc from name1 as a return value. Let's look at each of these options:
Passing s in via a double pointer
void name1(struct stos **s)
{
/* sanity check */
if(s == NULL)
return;
/* now, allocate enough space for four integers and make
* whatever s points to, point to that newly allocated
* space.
*/
*s = malloc(4 * sizeof(int));
}
And calling it from main requires us to use the "address-of" operator:
struct stos *s = NULL;
/* we need to pass a pointer to s into name1, so get one. */
name1(&s);
/* malloc can fail; check the result! */
if(s == NULL)
return -1;
Returning a pointer to the allocated memory from name1
struct stos *name1()
{
return malloc(4 * sizeof(int));
}
Calling this from main is slightly easier:
struct stos *s = name1();
/* malloc can fail; check the result! */
if(s == NULL)
return -1;
Changing your code to what I show you here will fix this issue (but there may be others) but let me touch briefly upon something else:
The other bug
The crash you encounterd crops up partially because of the problem we just covered; another issue is that inside name2 you are calling realloc. The pointer you pass into realloc however, is not a pointer that you got back from malloc or realloc, which is what realloc expects. It points to stosik instead. So that code causes undefined behavior and after that anything can happen.
If you're lucky (it seems you were), it will just crash right then and there and if you're not... well, who knows what will happen?
if you want to dynamically allocate s in name1 you need it to be declared as name1(struct stos** s) and pass pointer to the pointer where the allocated memory should appear.
Your main allocates stosik staticaly, meaning you don't need to do any further dynamic allocation. Then when you try doing name1(statically allocated mem) it does … um, something. I don't know what, but certainly not what you expect.

A segmentation fault with malloc while populating a structure fields in a function

I have a struct defined as
struct _element;
typedef struct _element Element;
struct _element {
char* StudentName;
char* StudentID;
int StudentMarks;
};
A pointer to an Element struct is declared globally as
Element * ePtr;
Now I have a function that returns a pointer to an Element struct. This is defined as shown below. The same ePtr which was declared globally is populated in this function and then returned.
Element * CreateElement(char * jName, char * jID, int jMarks)
{
printf("CreateElement \n");
puts(jName); puts(jID); printf("%d\n",jMarks);
ePtr->StudentName = (char*)malloc(sizeof(char)*strlen(jName));
strcpy(ePtr->StudentName, jName);
printf("After Creation \n");
puts(ePtr->StudentName);
return ePtr;
}
I am calling this function using
ePtr = CreateElement(iName,iID,iMarks);
from another function. The values stored in the parameters are correct, as shown by puts and printf commands just below the function call line.
My problem is that I'm getting a segmentation fault at the
ePtr->StudentName = (char*)malloc(sizeof(char)*strlen(jName));
line. I checked the same using gdb.
Are you allocating any memory for ePtr?
Just declaring a pointer to this struct globally isn't enough: you'll need to malloc some memory for it also: ePtr = malloc(sizeof(Element);.
Also be sure to add an extra slot in the malloc for your strings for the null terminator.
Generally, always initialize your pointers to NULL - you can do that when you declare the global: Element *ePtr = NULL;. Furthermore, try to get your ePtr out of the global-scope, and, check for NULL before you use a pointer, as with ePtr in your CreateElement method.
You need to assign some memory for ePtr before you can assign memory to the char* that it contains. Do a malloc on your ePtr at the start of the function.
There is also little point in declaring ePtr globally, but this isn't what is breaking the program.
ePtr = (Element*)malloc(sizeof(Element));
You should probably also check if ePtr is null after this before using it (can be null if out of memory as well as some other issues).
You don't assign any memory to
ePtr = (Element*)malloc(sizeof(Element));
before you start assigning values to it and ultimately return it from the function.
Also you need to allow space for the nul terminator of your string
ePtr->StudentName = (char*)malloc(sizeof(char)*(strlen(jName) + 1));
Finally don't forget to allocate memory for and copy the value of the ID, and copy the studentMarks into Element.
Remember, the Element is fixed-size. It needs memory to hold the two char * as well as the one int. It does not matter that the strings are variable length when allocating memory for Element.

Resources