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.
Related
Let’s say I have a pointer and allocate some memory for it. In case malloc would return a null pointer for whatever reasons, is it considered good practice to free it? Does it change something in this case? Is a check for malloc returning a null pointer even necessary?
char *some_function()
{
char *ptr = (char *)malloc(sizeof(char) * 10);
if (ptr == NULL)
{
free(ptr);
return NULL;
}
//some operations with the pointer
}
A check for malloc returning NULL is definitely necessary, since you cannot use NULL as a pointer to memory.
On the other hand, free(NULL) does nothing. (That's guaranteed by the standard.) So you can do that if you want to, but there's absolutely no point. If malloc returned NULL, no memory was allocated so there is nothing to free.
The point of free(NULL) being legal (and doing nothing) is that it lets you call free on any pointer returned by malloc, which simplifies resource freeing:
void do_something(unsigned n) {
int* data = malloc(n * sizeof(*data));
if (data) {
// Do something
}
else {
sprintf(stderr, "Couldn't allocate temporary vector of %ud ints\n", n);
}
free(data);
}
#include<stdio.h>
void trimSpace(char *s) {
char *t = s;
while(s = t, t[0] == ' '){ //checks initial array is space
while (*(s) = *(s+1),*s++ != '\0') { . //if so then move all data to left
}
}
printf("%s",s);
//free(s);
//free(t);
}
int main(){
char s[] = " abcdefghijklmnopqrstuvwxyz";
trimSpace(s);
return 0;
}
is it possible to free the pointers. i am getting
ERROR: Invalid free() / delete / delete[] / realloc()
(Stopped running after the first error. Please fix your code.)
The free function is used to deallocate memory that was returned from malloc and return it to the heap's available space. Only a pointer returned from malloc, calloc, or realloc may be passed to free.
You're not allocating memory dynamically, so no need to call free.
A pointer is a variable capable of storing an address of another variable i.e. it is like other variables. Static memory allocation is done at compile time and stack is used to manage this. As soon as the scope of variable is over, memory is freed. Only the dynamic memory allocated during runtime using heap can be freed using the free() function
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.
This question already has answers here:
Why doesn't free(p) set p to NULL?
(9 answers)
Closed 5 years ago.
After I call free on a struct variable in C, and then check if that variable is NULL, it shows me that it is NOT NULL. So free did not work? My code:
struct main_struct {
struct my_file *file;
};
struct my_file {
char *host;
int port; // this cannot be malloc'ed and free'ed
};
struct my_file* read_file() {
FILE *f;
struct my_file *file;
//open FILE for reading..
file = malloc(sizeof(struct my_file)); //allocate memory for my_file struct
memset(file, 0, sizeof(struct my_file));
// while loop to read file content..
// in the loop:
char *value = line;
file->host = malloc(sizeof(char) * strlen(value)); //allocate memory for host member variable
strncpy(file->host, value, strlen(value)); //assign value to host variable
return file;
}
int main() {
struct main_struct *mstr;
mstr = malloc(sizeof(struct main_struct)); //allocate memory to main_struct
memset(mstr, 0, sizeof(struct main_struct));
mstr->my_file = read_file(); //call to read file, allocate mem for my_file struct and the 'host' member variable
// some code
// call free here:
if(mstr->my_file->host != NULL) {
free(mstr->my_file->host);
}
// check if mem has been freed:
if(mstr->my_file->host == NULL) {
printf("mstr->my_file->host is NULL, good.\n");
} else {
printf("mstr->my_file->host is NOT NULL, bad.\n"); // I see this.
}
// I also try to free mstr->my_file:
if(mstr->my_file != NULL) {
free(mstr->my_file);
}
// check if mem has been freed:
if(mstr->my_file == NULL) {
printf("mstr->my_file is NULL, good.\n");
} else {
printf("mstr->my_file is NOT NULL, bad.\n"); // I see this.
}
// and also mstr itself..
}
Am I using the free function correctly, because I have seen examples where free has been called like this:
free(&mystruct->myfile->host); by sending the address of the pointer to free. But I think that the way I am calling free now, is correct..?
free(x) doesn't set x no NULL automatically, it just deallocates the memory and leaves x pointing to an invalid location. If you want to free x you can use a function like
void clear(void** ptr) { free(*ptr); *ptr = NULL; }
...
free(&(mstr->my_file->host));
Or you can do it manually each time. The comma operator can help here:
mstr->my_file->host = (free(mstr->my_file->host), NULL);
Edit: if you happen to be using glib (and its memory management wrappers), there is g_clear_pointer and g_clear_object to help with this.
free(&foo) is always wrong. You can only free pointer values that were returned from malloc / calloc / realloc (and wrappers such as strdup). &foo is the address of an existing variable (managed by the compiler).
free(ptr) will not set ptr to NULL. In general, a function call f(x) cannot modify x because C passes arguments by value. It will simply release the memory behind ptr, without touching ptr itself.
free(ptr) is a bit of a special case, because afterwards the value of ptr is indeterminate, which means your if(mstr->my_file->host != NULL) check actually has undefined behavior (looking at an indeterminate value is not allowed).
See also http://c-faq.com/malloc/ptrafterfree.html.
Random comments:
Never use strncpy. It is not a string function (in the sense that it doesn't work with or produce C strings), and its behavior will bite you at some point.
Multiplying by sizeof (char) is pointless: sizeof (char) is 1 by definition.
malloc + memset can be combined by using calloc to get zero-initialized memory. (In some cases calloc is also much faster than malloc/memset.)
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.