I have a C program that uses char *str[xx] staff frequently.
Some of the strings are filled using assignment operator(=) and need not be freed.
But some other(in the same array) are filled using strdup() which needs to be freed at the end of the program:
char *str[10];
str[i]="Hi";
str[k]=strdup("hi");
both of the string pointers are non null, and freeing str[i] will naturally generate "seg fault".
My problem is that at the end of my program, I don't have a track of which pointer is pointing to a string generated by strdup() . can you help my how I can find the string generated by strdup so that i can free them up?
thank you
Unfortunately there is no language feature by which you can (portably) distinguish a pointer which points to a dynamically allocated memory from the one that doesn't. You can just manually keep a list of indices for which it was allocated dynamically. Or alternatively, choose to ALWAYS allocate on the heap, if performance is not a great issue.
The proper way of handling this is to keep track of what has been dynamically allocated, through malloc() or strdup().
You have to refactor your program to reach this goal.
Perhaps you could use a naming convention to help you remember which is which:
char *str[10];
char *str_p[10];
str[i]="Hi";
str_p[k]=strdup("hi");
(or use a structure with a pointer and a flag which indicates that this particular pointer was dynamically allocated)
Related
Which strings ought I to free in C on my own, using free()¹?
My state of knowledge:
char a[256];: no
char *a = "abcdefg";: no
char *a = malloc(15L);: yes
a string returned by getenv(): no
strings returned by Windows functions²: ???
¹ or LocalFree()/GlobalFree()/VirtualFree()
² in particular by GetCommandLineW()
This will always be mentioned in the documentation for any API you use that returns strings (or other data larger than a single simple value such as an integer).
Yes, this means you have to read the documentation thoroughly for all such API functions, in order to keep track and not leak memory.
The only chunks of memory that must be freed are those that were previously malloced.
Now the questions are "is this pointer a pointer to memory that was created by malloc ?" and, if so, "am I supposed to free it myself or will some other function take care of it ?"
There are no easy answers to these questions, generally the documentation will tell you so, but the rule of thumb is that the module that takes care of memory creation also takes care of deallocation. So, if the library you use expects you to provide already allocated memory, you are supposed to free it, too, when needed.
In case of explicit dynamic allocation i.e. malloc/alloc/realloc you have to explicitly free it. But now that you have mentioned about strings there is a special function strdup() which under-the-hood malloc for you when you call it.
In case of strdup(), you have to make sure that without you allocating you MUST free it.
When i use malloc in C, i use it within different functions and free the pointers i used in malloc outside of the function.
Function 1: allocates memory for a point that is a string "hi" it returns the pointer that has "hi"
function 2: I have a pointer and allocate memory for this pointer, it then contains "hi" too. Even though i haven't done anything to this pointer.
Why does this happen? How do i stop this?
I've tried to reallocate memory and free multiple times but nothing works.
Your question is unclear. If you are allocating memory with malloc, the library does not initialize the memory to which a pointer is returned. It may contain anything: in your case, it may well contain the same string, but is does not mean anything.
Post your code so we can confirm this diagnostic.
I am struggling to wrap my head around malloc in c - specifically when it needs to be free()'d. I am getting weird errors in gcc such as:
... free(): invalid next size (fast): ...
when I try to free a char pointer. For example, when reading from an input file, it will crash on certain lines when doing the following:
FILE *f = fopen(file,"r");
char x[256];
while(1) {
if(fgets(x,sizeof x,f)==NULL) break;
char *tmp = some_function_return_char_pointer(x); //OR malloc(nbytes);
// do some stuff
free(tmp); // this is where I get the error, but only sometimes
}
I checked for obvious things, such as x being NULL, but it's not; it just crashes on random lines.
But my REAL question is - when do I need to use free()? Or, probably more correctly, when should I NOT use free? What if malloc is in a function, and I return the var that used malloc()? What about in a for or while loop? Does malloc-ing for an array of struct have the same rules as for a string/char pointer?
I gather from the errors I'm getting in gcc on program crash that I'm just not understanding malloc and free. I've spent my quality time with Google and I'm still hitting brick walls. Are there any good resources you've found? Everything I see says that whenever I use malloc I need to use free. But then I try that and my program crashes. So maybe it's different based on a variable's scope? Does C free the memory at the end of a loop when a variable is declared inside of it? At the end of a function?
So:
for(i=0;i<100;i++) char *x=malloc(n); // no need to use free(x)?
but:
char *x;
for(i=0;i<100;i++) {
x=malloc(n);
free(x); //must do this, since scope of x greater than loop?
}
Is that right?
Hopefully I'm making sense...
malloc() is C's dynamic allocator. You have to understand the difference between automatic (scoped) and dynamic (manual) variables.
Automatic variables live for the duration of their scope. They're the ones you declare without any decoration: int x;
Most variables in a C program should be automatic, since they are local to some piece of code (e.g. a function, or a loop), and they communicate via function calls and return values.
The only time you need dynamic allocation is when you have some data that needs to outlive any given scope. Such data must be allocated dynamically, and eventually freed when it is no longer necessary.
The prime usage example for this is your typical linked list. The list nodes cannot possibly be local to any scope if you are going to have generic "insert/erase/find" list manipulation functions. Thus, each node must be allocated dynamically, and the list manipulation functions must ensure that they free those nodes that are no longer part of the list.
In summary, variable allocation is fundamentally and primarily a question of scope. If possible keep everything automatic and you don't have to do anything. If necessary, use dynamic allocation and take care to deallocate manually whenever appropriate.
(Edit: As #Oli says, you may also want to use dynamic allocation in a strictly local context at times, because most platforms limit the size of automatic variables to a much smaller limit than the size of dynamic memory. Think "huge array". Exceeding the available space for automatic variables usually has a colourful name such as "pile overrun" or something similar.)
In general, every call to malloc must have one corresponding call to free.* This has nothing to do with scope (i.e. nothing to do with functions or loops).
* Exceptions to this rule include using functions like strdup, but the principle is the same.
Broadly speaking, every pointer that is ever returned by malloc() must eventually be passed to free(). The scope of the variable that you store the pointer in does not affect this, because even after the variable is no longer in scope, the memory that the pointer points to will still be allocated until you call free() on it.
Well, the scope of the malloc'd memory lays between calls to malloc and free or otherwise until process is stopped (that is when OS cleans up for the process). If you never call free you get a memory leak. That could happen when address that you can pass to free goes out of scope before you actually used it - that is like loosing your keys for the car, car is still there but you can't really drive it. The error you are getting is most likely either because function returns a pointer to some memory that was not allocated using malloc or it returns a null pointer which you pass to free, which you cannot do.
You should free memory when you will no longer be accessing it. You should not free memory if you will be accessing it. This will give you a lot of pain.
If you don't want memory leak, you have to free the memory from malloc.
It can be very tricky. For example, if the // do some stuff has a continue, the free will be skipped and lead to memory leak. It is tricky, so we have shared_ptr in C++; and rumor has it salary of C programmer is higher than C++ programmer.
Sometimes we don't care memory leak. If the memory holds something that is needed during the whole lifetime of execution, you can choose not to free it. Example: a string for environment variable.
PS: Valgrind is a tool to help detect memory bugs. Especially useful for memory leak.
malloc(n) allocates n bytes of memory from a memory location named heap and then returns a void* type of pointer to it. The memory is allocated at runtime. Once you have allocated a memory dynamically, scope does not matter as long as you keep a pointer to it with you(or the address of it specifically). For example:
int* allocate_an_integer_array(int n)
{
int* p = (int*) (malloc(sizeof(int)*n));
return p;
}
This functions simply allocates memory from heap equal to n integers and returns a pointer to the first location. The pointer can be used in the calling function as you want to. The SCOPE does not matter as long as the pointer is with you..
free(p) returns the memory to heap.
The only thing you need to remember is to free it as if you don't free it and lose the value of its address, there will bw a memory leak. It is so because according to OS, you are still using the memory as you have not freed it and a memory leak will happen..
Also after freeing just set the value of the pointer to null so that u don't use it again as the same memory may be allocated again at any other time for a different purpose....
So, all you need to do is to be careful...
Hope it helps!
I'm working on ANSI C.
I have a string object which created with array of char..
I think the object make a memory leak..
when I run my program about five minutes (maybe almost 10000 iteration) my used memory become bigger and bigger..
I tried to free my object used memory with free and delete function. but, delete isn't a valid function. in the other side, free looks like running well first. but I got free():invalid pointer..
How can I fix this? I can do it differently?
here's a little of my code..
char *ext;
ext = calloc(20, sizeof(char));
//do something with ext
free(ext);
In C, you allocated memory on the heap with malloc, and release is with free. So you are correct there. delete is used in C++, and then, only if the memory was allocated with the new operator.
If you are getting an invalid pointer error in your call to free, then there is likely a bug somewhere in the code, if you post it we could take a look at it.
Maybe you're writing past the end of the allocated memory. With
calloc(20, sizeof(char))
you allocate space for 20 characters (19 "regular" and a null terminator for strings).
Make very sure none of your strcat() try to write "regular" characters beyond str[18].
Without more code:
An array in memory just prior to what ext points to overran its storage and corrupted a type of "header" that malloc() uses to track the size of the memory for subsequent calls to free() (think of ((size_t *)ext)[-1] holding the size from the malloc).
You used a negative array index into ext[negative] that did the same corruption.
ext somehow gets modified.
Please excuse my C newbiness.
Consider the following C procedure:
int doSomething() {
char *numbers="123456";
...
}
Before this procedure exits should I be releasing the 'numbers' pointer?
No, you didn't malloc it. Why should you release it?
Often, the string is placed in a read only section of the executable.
In C language you don't and can't "release" pointers. Pointers are ordinary scalar variables. There's nothing you can do with them in terms of "releasing" or anything like that.
What one can be "releasing" is the memory a pointer is pointing to. But in C you only have to release memory that was explicitly allocated by malloc/calloc/realloc. Such memory is released by calling free.
Note again, that in your program you might have several (a hundred) pointers pointing to the same block of allocated memory. Eventually, you'll have to release that memory block. But regardless of how many pointers you have pointing to that block, you have to release that memory block exactly once. It is your responsibility to make sure that you release it. And it is your responsibility to make sure you released it exactly once. I'm telling you this just to illustrate the fact that what you release is the memory block, not the pointers.
In your example, your pointer points to a memory block that was never allocated by any of the aforementioned functions. This immediately means that you don't need to release anything.
No, there is no need to do so, and doing so is incorrect (thanks dmckee). The character string will be in the data segment of the binary, so it can't be freed. The memory was not dynamically allocated.
"numbers" will be on the stack, so it will go away when the function returns.
you don't actually need to call delete or free , these operators are only used to clean up memory that have been allocated my runtime memory allocator like malloc, calloc , GlobalAlloC, HeapAlloc and so forth. When you define a pointer like in the example you are actually allocating space for array of character in the the execuatable file. so bigger the string length bigger will be the executable size thus increasing your working set.
No; there's nothing to release. The string literal "123456" is an array of char (const char in C++) with static extent. The memory for it is allocated at program startup and held until the program exits. All you've done is assign the address of the string literal to numbers; you haven't actually allocated any memory.
NO, since it was not allocated by malloc/ calloc / realloc.
It will be automatically "freed" because it is an automatic variable.
No, it points to pre-allocated memory in process data segment. Only free(3) what you have malloc(2)-ed (modulo some library functions like getaddrinfo(3)/freeaddrinfo(3).)