I am in a bit of dilemma, thus, first of all I would like to apologize of if the next questions will be a bit more noobish or if they have been asked before (I couldn't find the answers for those though).
Anyway, I will explain it by giving a task as an example (it's not homework, it's just for the sake of my question). Here it goes:
Given a string from stdin index each word, then print each word on one line.
Example:
str[] = "Stack is awesome"
str_index {
[0] => "Stack"
[1] => "is"
[2] => "awesome"
}
I know that there are many ways to solve this, but, again, for the sake of my question
Bare this solution:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/* fgets adds an unwanted '\n' at the end, so I made
* a special function to read from stdin that removes
* that '\n'.
*/
int read(char *str, int size) {
// fgets adds an unwanted '\n' at the end, so we remove it
fgets(str, size, stdin);
int length = strlen(str);
str[length - 1] = '\0';
return length;
}
/* A function that breaks a string into words, indexes them
* and prints them out, all done dynamically with malloc.
*/
void str_index(char *str) {
char **index, *ptr;
int i = 0, number_of_words;
index = malloc(sizeof(char *));
ptr = strtok(str, " ");
for(i = 0; ptr != NULL; i++) {
index = realloc(index, (i + 1) * sizeof(char *));
index[i] = malloc(50 * sizeof(char));
strcpy(index[i], ptr);
ptr = strtok(NULL, " ");
}
number_of_words = i;
for(i = 0; i < number_of_words; i++) {
printf("%s\n", index[i]);
}
return;
}
int main() {
char str[250];
read(str, 250);
str_index(str);
return 0;
}
QUESTIONS
Where do I have to free the arrays that I have allocated dynamically
in str_index?
Do we have to free them within the function str_index? If so, why?
What I know is that when a function is done executing all local
variables are destroyed.
Why do we have to free them in main? Isn't main a function aswell,
thus upon finishing executing it all variables defined in that function are destroyed.
I'm guessing you are doing a university course. The problem (in my opinion) with university courses is that they start by teaching high level languages where everything is done magically, and then teach you a low level language. If I ruled the world, everyone would start with assembler, then C, then be allowed to 'progress' to Java etc.
To your question, the problem you have is the assumption that 'things might be done magically'. C doesn't do very much magically at all. In particular, if you malloc() or calloc() anything, or allocate anything using something that uses the heap allocator (for instance strdup()), it's your responsibility to free it. And you will need to do that explicitly. If you don't, you will have a memory leak. The first order problem is thus 'if I allocated it, I must ensure it is freed'. The second order problem is 'if I used a library that might have allocated stuff, I need to work out how to ensure it knows I've done, so it can free stuff'. If you bear this in mind, your C programming life will be happy, and valgrind will be your friend.
Let's now consider your questions:
You ask where you should free your dynamically allocated memory. Technically, in this example, you don't need to, because exiting your program will free all memory on the heap. However, let's suppose you want to use this function repeatedly. You want to free the allocation as soon as you no longer have a use for it. In the example presented, that would be immediately before the return. If you had other exits from the function, then make sure you free your allocation before every return. A useful error handling hint is to exit via the same code, and whenever you free() the allocation, also set the pointer to the allocation to NULL. On entry, also initialise the pointer to NULL. Then on exit (a valid use of goto), you can simply check the pointer against NULL, and if it is not null, free() it. (In fact once you get really cocky, you will know free() on NULL on most platforms is a no-op, so you can unconditionally free it). The setting the pointer to NULL bit is to avoid a double free.
This is the difference between the stack and the heap. Local variables are allocated on the stack. C destroys them automatically when a function returns. This is one of the few bits of magic C does. Note that I said it destroys the variables, not the things they point to. So if you have a pointer to allocated (heap) memory in a local variable, and the function returns, it will 'free' the variable (in the sense it will no longer be on the stack), but the allocated (heap) memory will not be freed. This is why you must free heap allocated memory only referenced in a function before the pointers to it are destroyed by exiting the function - see the answer to 1 above.
You don't need to free anything in main() in your example. If you had coded your function to return a pointer to memory on the heap (for instance if you'd coded the equivalent of strdup()) then your main() function would need to free() that. That brings up the important point that what the caller needs to free() depends on how the called function is designed. It's thus important that the called function makes this obvious in documentation.
Where do I have to free the arrays that I have allocated dynamically in str_index?
Just before the return; statement of your function str_index.
Do we have to free them within the function str_index?
Not necessary. Depends on the program requirement.
What I know is that when a function is done executing all local variables are destroyed.
Yes, it is true for space allocated on stack (if variable is not static), but not for the space allocated on heap.
Why do we have to free them in main?
Not necessary that it have to free in main. Depends on the program requirement.
Related
This question already has answers here:
Expanding an array with malloc
(4 answers)
In C, are arrays pointers or used as pointers?
(6 answers)
Closed 2 years ago.
I'm trying to reallocate memory using the realloc function, I saw that you need to use malloc before but I don't understand if you MUST use it because let's say I'm creating the following string:
char string[] = "fun";
would the realloc function work if I try to add more space?
that brings me to my question, I'm trying to simply add one letter at the end of the string, lets say 'p', but for some reason the program crushes on the realloc line every time I run it.
Here is my full code:
int main()
{
char string[] = "fun" ;
str_func(string);
printf("%s", string);
return 0;
}
void str_func(char* str)
{
str = (char*)realloc(str, strlen(str) + 2);
strcat(str, "p");
}
I also tried making a pointer to 'string' and sending the pointer, which results the same thing.
would the realloc function work if I try to add more space?
No, because that array is no allocated on the heap - in your case it is very likely allocated on the stack and can't get resized. Simply put: realloc doesn't recognize the pointer and doesn't know what to do with it, but tries to do something anyway, hence the crash.
You can only call realloc on a pointer that was previously passed to malloc, or on a null pointer. That's just how these functions work.
For details, see What gets allocated on the stack and the heap?.
I saw that you need to use malloc before but I don't understand if you MUST use it
If you need to use malloc before you can realloc something, then by definition you must only realloc things originally allocated with malloc.
You're trying to find some space between "need" and "must" that doesn't exist.
... for some reason the program crushes on the realloc
You already said you know you need to use malloc. Then you didn't use malloc, and you're asking why this is a problem. You could at least try doing the thing you "know" you need to do, to see if that solves the problem.
The program should probably look like
int main()
{
/* array is an automatic local variable. It wasn't dynamically allocated
in the first place, so can't be dynamically re-allocated either.
You cannot (and don't need to) free it either, it just goes out of scope
like any other automatic variable.
*/
char array[] = "fun";
/* you need to use malloc (or one of the other dynamic allocation functions)
before you can realloc, as you said yourself */
char *dynamic = malloc(1+strlen(array));
memcpy(dynamic, array, 1+strlen(array));
/* realloc can move your data, so you must use the returned address */
dynamic = str_func(dynamic);
printf("old:'%s', new:'%s'\n", array, dynamic);
/* not really essential since the program is about to exit anyway */
free(dynamic);
}
char* str_func(char* str)
{
char* newstr = realloc(str, strlen(str) + 2);
if (newstr) {
strcat(newstr, "p");
return newstr;
} else {
/* we failed to make str larger, but it is still there and should be freed */
return str;
}
}
Your original condition isn't quite correct: actually the pointer passed to realloc
... must be previously allocated by malloc(), calloc() or realloc() and not yet freed with a call to free or realloc
[OR] If ptr is NULL, the behavior is the same as calling malloc(new_size).
The realloc function only works with things that were originally created with a small group of allocation functions (such as malloc, calloc, or realloc itself), or the null pointer. Since string is none of those things, your code is not well-defined.
I am learning the basic of C programming and find it quite strange and difficult. Especially with dynamic memory allocation, pointer and similar things. I came upon this function and don't quite understand what is wrong with it.
char *strdup(const char *p)
{
char *q;
strcpy(q, p);
return q;
}
I think I have to malloc and free q. But the function " return q". Doesn't that mean that it will store q value in its own memory. So the data still be saved after the function executed?
When it is appropriate to use malloc? As I understand so far is that I have to malloc a new variable every time I need that variable declared in a function to be used elsewhere. Is that true? Is there any other situation where malloc is needed?
The type of q is a pointer, and pointers hold addresses -- so what you are returning is the address that pointer holds.
Until you give that pointer a valid address, it points off to who-knows-where, memory that you may or may not own and have the right to access. So, the strdup call will copy a string from the address held in p into some location you probably don't own.
If you had done a malloc first, and given q the results of the malloc, then q would hold a valid address, and your strdup would put the copy into memory that you did own (assuming you malloc'd enough space for the string -- a strlen on p would tell you how much you needed).
Then, when you returned q, you would be giving the caller the address as well. Any code with that address can see the string you put there. If some future code were to free that address, then what it holds is up in the air -- it could be anything at all.
So, you don't want to free q before you return the address that it holds -- you need to let the caller free the address it gets from you, when it is ready to do so.
In terms of when you malloc, yes, if you want to return an address that will remain viable after your function completes, you need to malloc it -- giving the caller the address of a local variable, for example, would be bad: the memory is freed when the function returns, you don't own it anymore.
Another typical use of malloc is for building up dynamic data structures like trees and lists -- you can't know how much memory you need up front, so you build the list or tree up as you need to, malloc'ing more memory for each node in the structure.
My personal rules are: use malloc() when an object is too big to put on the stack or/and when it has to live outside the scope of the current block. In your case, I believe, you should do something like the following:
char *strdup(const char *p)
{
char *q;
q = malloc(strlen(p) + 1);
if(NULL != q)
strcpy(q, p);
return q;
}
malloc(X) creates space (of size X bytes) on the heap for you to play with. The data that you write to these X byes stays put when your function returns, as a result, you can read what your strdup() function wrote to that space on the heap.
free() is used for freeing space on the heap. You can pass a pointer to this function that you obtained only as a result of a malloc() or realloc() call. This function may not clear out the data, it just means that a subsequent call to malloc() may return the address of the same space that you just freed. I say "may" because these are all implementaion defined and should not be relied upon.
In the piece of code you wrote, the strcpy() function copies the bytes one by one from p to q until it finds a \0 at the location pointed to by q (and then it copies the \0 as well). In order to write data somewhere, you need to allocate space first for the data to be written, hence, one option is that you call malloc() to create some space and then write data there.
Well, calling free() is not mandatory as your OS will reclaim the space allocated by malloc() when you program ends, but as long as your program runs, you may be ocupying more space than you need to - and that's bad for your program, for other programs, for the OS and the universe as a whole.
I think I have to malloc and free q. But the function " return q". Doesn't that mean that it will store q value in its own memory. So the data still be saved after the function executed?
No, your data won't be saved. In fact your pointer q is being used without allocating it's size can cause problems. Also, once this function execution complete, variable char* q will be destroyed.
You need to allocate memory to pointer q before copying data as suggested by #Michael's answer.But once you finish using the data return by this function, you will need to manually free() the memory you allocated or else it will cause memory leak (a situation where the memory is allocated but there is no pointer refer to that chunk of memory you allocated and hence will be inaccessible throughout program execution)
char *strdup(const char *p) // From #Michael's answer
{
char *q;
q = malloc(strlen(p) + 1);
if(NULL != q)
strcpy(q, p);
return q;
}
void someFunction()
{
char* aDupString = strdup("Hello World!!!");
/*... somecode use aDupString */
free(aDupString); // If not freed, will cause memory leaks
}
When it is appropriate to use malloc? Is there any other situation where malloc is needed?
It is appropriate to use in following situations:
1> The usage size of array are unknown at compile time.
2> You need size flexibility. For example, your function need to work with small data size and large data size. (like Data structure such as Link list,Stacks, Queues, etc.)
As I understand so far is that I have to malloc a new variable every time I need that variable declared in a function to be used elsewhere. Is that true?
I think this one is partially true. depending on what you are trying to achive, there might be a way to get around using malloc though. For example, your strdup can also be rewrite in following way:
void strdup2(const char *p, char* strOut)
{
// malloc not require
strcpy(strOut, p);
}
void someFunction()
{
char aString[15] = "Hello World!!!";
char aDupStr[sizeof(aString)];
strdup2(aString, aDupStr);
// free() memory not required. but size is not dynamic.
}
I am pretty new to C programming and I have several functions returning type char *
Say I declare char a[some_int];, and I fill it later on. When I attempt to return it at the end of the function, it will only return the char at the first index. One thing I noticed, however, is that it will return the entirety of a if I call any sort of function on it prior to returning it. For example, my function to check the size of a string (calling something along the lines of strLength(a);).
I'm very curious what the situation is with this exactly. Again, I'm new to C programming (as you probably can tell).
EDIT: Additionally, if you have any advice concerning the best method of returning this, please let me know. Thanks!
EDIT 2: For example:
I have char ret[my_strlen(a) + my_strlen(b)]; in which a and b are strings and my_strlen returns their length.
Then I loop through filling ret using ret[i] = a[i]; and incrementing.
When I call my function that prints an input string (as a test), it prints out how I want it, but when I do
return ret;
or even
char *ptr = ret;
return ptr;
it never supplies me with the full string, just the first char.
A way not working to return a chunk of char data is to return it in memory temporaryly allocated on the stack during the execution of your function and (most probably) already used for another purpose after it returned.
A working alternative would be to allocate the chunk of memory ont the heap. Make sure you read up about and understand the difference between stack and heap memory! The malloc() family of functions is your friend if you choose to return your data in a chunk of memory allocated on the heap (see man malloc).
char* a = (char*) malloc(some_int * sizeof(char)) should help in your case. Make sure you don't forget to free up memory once you don't need it any more.
char* ret = (char*) malloc((my_strlen(a) + my_strlen(b)) * sizeof(char)) for the second example given. Again don't forget to free once the memory isn't used any more.
As MByD correctly pointed out, it is not forbidden in general to use memory allocated on the stack to pass chunks of data in and out of functions. As long as the chunk is not allocated on the stack of the function returning this is also quite well.
In the scenario below function b will work on a chunk of memory allocated on the stackframe created, when function a entered and living until a returns. So everything will be pretty fine even though no memory allocated on the heap is involved.
void b(char input[]){
/* do something useful here */
}
void a(){
char buf[BUFFER_SIZE];
b(buf)
/* use data filled in by b here */
}
As still another option you may choose to leave memory allocation on the heap to the compiler, using a global variable. I'd count at least this option to the last resort category, as not handled properly, global variables are the main culprits in raising problems with reentrancy and multithreaded applications.
Happy hacking and good luck on your learning C mission.
Let's say we have the following scenario.
char* halfString(char* input) {
char* output = malloc(strlen(input));
int i = 0;
for(i = 0; i < strlen(input); i++)
output[i] == input[i];
output[i] = '\0';
return output;
}
int main() {
char* input = "Hello";
char* output = halfString(input);
printf("%s\n",output);
free(output);
}
Will the call "free(output)" free the memory of char* output that is local to main and free the memory of the char* output local to halfString()? OR is there still a memory leak for the char* output local to halfString()?
Any help is appreciated.
There is no memory leak.
You seem to be confused, though, about how heap allocation works. There is only one chunk of memory being allocated here, and it is not "local" to either halfString() or to main(). The allocated chunk exists in the heap, and is not scoped to a particular code block.
malloc() returns a pointer to it. You then return that pointer back to main(), but the value of the pointer is still the same: it points to the same address in memory, the same chunk of heap. main() then properly frees it.
As a design consideration, this is often not the best thing to do. In general, a caller may not necessarily know that the pointer returned by halfString() points to a chunk that was allocated with malloc() and that they need to free() it. This would have to be very clearly and carefully documented. A better solution might be to provide a freeHalfString() function which does the freeing; then from a maintenance standpoint, those two functions can be put in the same place and maintained concurrently, so that the caller doesn't need to worry about how the buffer was allocated, or how to free it.
(As others have pointed out, you also have a buffer overflow because you need to allocate strlen(input) + 1 bytes to include the NULL terminator.)
The code is mostly correct, because malloc() puts memory on the heap and free() frees it. It does not matter which functions they get called from.
That said, there is an important off-by-one error:
char* output = malloc(strlen(input) + 1); // Don't forget +1
The strlen() function returns the number of characters in the string, not including the terminator.
These errors can be often caught automatically by using certain tools like Mudflap (compile with -fmudflap, if using GCC) and Valgrind.
Algorithmic complexity
There is a problem with the algorithmic complexity of your code, which will probably disappear with good compilers when optimization is enabled.
for(i = 0; i < strlen(input); i++)
This will call strlen(), which is O(N), and it will call strlen() O(N) times, giving O(N2) asymptotic performance. We can do better, here are two fixes:
// Version 1
size_t i, n = strlen(input);
for (i = 0; i < n; i++)
...
// Version 2
size_t i;
for (i = 0; input[i] != '\0'; i++)
...
You seem to be confusing two related items: buffers, and pointers. A buffer is a block of memory which, in the context of your question, is allocated using malloc(). A pointer is related in that it points to a buffer, but it's not the buffer itself.
In your halfString() function, you allocate a buffer, and you store the address of (pointer to) that buffer in your local output.You then return it to the caller, main(), which coincidentally has a variable of the same name which will point to the same buffer.
Now, in main(), when you free(output); you're not freeing a pointer, you're freeing the buffer that pointer points to. It doesn't matter where the buffer was allocated, it only matters that the buffer was allocated (and not already freed). After this call your main function's output variable still exists, and it still has an address to what was once a valid buffer -- but that buffer must not be used of course, since it's no longer valid.
Now as to your question "Is there a memory leak?" -- You've malloc'd a single buffer, then you free'd that same buffer, so no link. Always properly pair a malloc with a free, and you'll be in good shape.
The free() will free the memory allocated in called function itself. it is not local to any function because malloc allocates memory on heap.
what you call as local memory is on stack that will be freed when function returns.
So what allocation done using malloc is on heap and the procedure you used will free memory allocated in called function.
This code will work correctly (if the off-by-one error others mention is fixed). The call in main will free the memory allocated in halfString.
There is no "memory of output that is local to main". What is local to main is the output pointer, which was allocated on the stack and will go out of scope when main exits.
There is no memory leak. System knows how much memmory is associated with pointer, and since you can not free part of memory block allocated with malloc, it will free all.
I am working with my first straight C project, and it has been a while since I worked on C++ for that matter. So the whole memory management is a bit fuzzy.
I have a function that I created that will validate some input. In the simple sample below, it just ignores spaces:
int validate_input(const char *input_line, char** out_value){
int ret_val = 0; /*false*/
int length = strlen(input_line);
out_value =(char*) malloc(sizeof(char) * length + 1);
if (0 != length){
int number_found = 0;
for (int x = 0; x < length; x++){
if (input_line[x] != ' '){ /*ignore space*/
/*get the character*/
out_value[number_found] = input_line[x];
number_found++; /*increment counter*/
}
}
out_value[number_found + 1] = '\0';
ret_val = 1;
}
return ret_val;
}
Instead of allocating memory inside the function for out_value, should I do it before I call the function and always expect the caller to allocate memory before passing into the function? As a rule of thumb, should any memory allocated inside of a function be always freed before the function returns?
I follow two very simple rules which make my life easier.
1/ Allocate memory when you need it, as soon as you know what you need. This will allow you to capture out-of-memory errors before doing too much work.
2/ Every allocated block of memory has a responsibility property. It should be clear when responsibility passes through function interfaces, at which point responsibility for freeing that memory passes with the memory. This will guarantee that someone has a clearly specified requirement to free that memory.
In your particular case, you need to pass in a double char pointer if you want the value given back to the caller:
int validate_input (const char *input_line, char **out_value_ptr) {
: :
*out_value_ptr =(char*) malloc(length + 1); // sizeof(char) is always 1
: :
(*out_value_ptr)[number_found] = input_line[x];
: :
As long as you clearly state what's expected by the function, you could either allocate the memory in the caller or the function itself. I would prefer outside of the function since you know the size required.
But keep in mind you can allow for both options. In other words, if the function is passed a char** that points to NULL, have it allocate the memory. Otherwise it can assume the caller has done so:
if (*out_value_ptr == NULL)
*out_value_ptr =(char*) malloc(length + 1);
You should free that memory before the function returns in your above example. As a rule of thumb you free/delete allocated memory before the scope that the variable was defined in ends. In your case the scope is your function so you need to free it before your function ends. Failure to do this will result in leaked memory.
As for your other question I think it should be allocated going in to the function since we want to be able to use it outside of the function. You allocate some memory, you call your function, and then you free your memory. If you try and mix it up where allocation is done in the function, and freeing is done outside it gets confusing.
The idea of whether the function/module/object that allocates memory should free it is somewhat of a design decision. In your example, I (personal opinion here) think it is valid for the function to allocate it and leave it up to the caller to free. It makes it more usable.
If you do this, you need to declare the output parameter differently (either as a reference in C++ style or as char** in C style. As defined, the pointer will exist only locally and will be leaked.
A typical practice is to allocate memory outside for out_value and pass in the length of the block in octets to the function with the pointer. This allows the user to decide how they want to allocate that memory.
One example of this pattern is the recv function used in sockets:
ssize_t recv(int socket, void *buffer, size_t length, int flags);
Here are some guidelines for allocating memory:
Allocate only if necessary.
Huge objects should be dynamically
allocated. Most implementations
don't have enough local storage
(stack, global / program memory).
Set up ownership rules for the
allocated object. Owner should be
responsible for deleting.
Guidelines for deallocating memory:
Delete if allocated, don't delete
objects or variables that were not
dynamically allocated.
Delete when not in use any more.
See your object ownership rules.
Delete before program exits.
In this example you should be neither freeing or allocating memory for out_value. It is typed as a char*. Hence you cannot "return" the new memory to the caller of the function. In order to do that you need to take in a char**
In this particular scenario the buffer length is unknown before the caller makes the call. Additionally making the same call twice will produce different values since you are processing user input. So you can't take the approach of call once get the length and call the second time with the allocated buffer. Hence the best approach is for the function to allocate the memory and pass the responsibility of freeing onto the caller.
First, this code example you give is not ANSI C. It looks more like C++. There is not "<<" operator in C that works as an output stream to something called "cout."
The next issue is that if you do not free() within this function, you will leak memory. You passed in a char * but once you assign that value to the return value of malloc() (avoid casting the return value of malloc() in the C programming language) the variable no longer points to whatever memory address you passed in to the function. If you want to achieve that functionality, pass a pointer to a char pointer char **, you can think of this as passing the pointer by reference in C++ (if you want to use that sort of language in C, which I wouldn't).
Next, as to whether you should allocate/free before or after a function call depends on the role of the function. You might have a function whose job it is to allocate and initialize some data and then return it to the caller, in which case it should malloc() and the caller should free(). However, if you are just doing some processing with a couple of buffers like, you may tend to prefer the caller to allocate and deallocate. But for your case, since your "validate_input" function looks to be doing nothing more than copying a string without the space, you could just malloc() in the function and leave it to the caller. Although, since in this function, you simply allocate the same size as the whole input string, it almost seems as if you might as well have the caller to all of it. It all really depends on your usage.
Just make sure you do not lose pointers as you are doing in this example
Some rough guidelines to consider:
Prefer letting the caller allocate the memory. This lets it control how/where that memory is allocated. Calling malloc() directly in your code means your function is dictating a memory policy.
If there's no way to tell how much memory may be needed in advance, your function may need to handle the allocation.
In cases where your function does need to allocate, consider letting the caller pass in an allocator callback that it uses instead of calling malloc directly. This lets your function allocate when it needs and as much as it needs, but lets the caller control how and where that memory is allocated.