Can I return buffer created in functions? - c

char * return_buffer()
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "%s", "test");
return buffer;
}
buffer is created in the function, can I return the buffer directly? after the function returns, the buffer would disappear?

You are creating a statically allocated buffer, which means that it is being created on the stack. When the function returns, it will give you an address on the stack that is no longer in use. So if you make more function calls, the data it stores will likely corrupt.
It is much better to allocate it to the heap by calling malloc.

You will need to allocate the buffer on heap using malloc.
buffer is a local/automatic variable and is not guaranteed to exist after the function returns.Using any such buffer beyond the function scope will result in Undefined Behavior.

Yes. This buffer is a local variable using stack and will be released once you exit the function. Use malloc to allocate a dynamic memory buffer.

In this case, no you cannot. More like you can but you should not do this.
Here the buffer is created on stack which will be reused.
You can return when you allocate with malloc or similar functions.

This is not possible and may lead to crash. Here the memory is allocated on the stack and once the function returns memory will be freed. If you want to return buffer from a function then you have to allocate memory on the heap. You can use malloc/calloc for this. Read more

No, you can't return pointers to local variables.
The best way to write such functions is to leave allocation to the caller. The advantages are: 1) the code is independent of the memory allocation method and can be used both with statically and dynamically allocated memory, and 2) keep algorithms and memory allocation separated, so that the algorithms only concern themselves with the main task at hand and don't concern themselves with side-tasks irrelevant to the algorithm itself, such as memory allocation.
This kind of program design is very common (for example it is used by the Windows API).
Example:
void print_buffer (char* buffer, size_t size)
{
snprintf(buffer, size, "%s", "test");
}

Related

Does malloc() reuse the same memory address in loop?

I'm starting to learn C programming and stumbled upon a situation that shows my lack of understanding of how memory allocation with malloc() works.
In a loop like the following:
// will only know `xlen` at runtime so I guess I have to use malloc here
char *x = malloc((xlen + 1) * sizeof(*x));
assert(x != NULL); // memory allocation failed
while (fgets(line, sizeof(line), fp) != NULL) {
strncpy(x, line, xlen); // copy first xlen characters of line
x[xlen] = '\0'; // ensure null terminating string
// do something with x
// x can now be "reused" for another line/loop iteration
// free(x) - errors out with "pointer being freed was not allocated"
}
fclose(fp)
free(x);
If the statement free(x) is called inside the loop then when I run this program I get an error message something like a.out(37575,0x7fff964ce3c0) malloc: *** error for object 0x7fab47c02630: pointer being freed was not allocated.
Why am I seeing this error message and what is causing it?
Will the memory address block of x be "re-used" at each iteration of the loop? (I'd say yes, and that would actually be what I wanted in this case) In this case, is it safe to only free the allocated memory of x outside the scope of the loop?
free(x); frees the memory allocated by char *x = malloc(.... It frees all of the memory, and you don't have to worry about how much memory that was, as it keeps track of that. You just have to call free(x); once as you correctly do. This is why you get the error if you free it inside the loop.
Does it mean that the memory address block of x will be "re-used" at
each iteration? (I'd say yes, and that would actually be what I wanted
in this case)
Yes, you use the same memory. It overwrites the memory every time.
In this case, is it safe to only free the allocated memory of x
outside the loop scope?
Yes, you have to free it outside of the loop. Because if you free it, then all of it is freed. If you did that inside the loop, then it would be undefined behavior to keep accessing that memory in following loop iterations.
The malloc() function provides a pointer to an area of memory that can then be used just like any pointer to a memory location.
The way to think of malloc() and free() is to consider it in terms of who owns a memory area. The malloc() function owns the memory that it is managing. When you call the malloc() function, or calloc() function, the function takes some of the memory it is managing and transfers ownership to you. When the function is called and the memory allocated there is a transfer of ownership from the memory management system of malloc() to you and at that point you own that memory and it is up to you to manage it. When the free() function is called to release the memory, you are transferring ownership of the memory area from you back to the memory management system of malloc().
Whenever a transfer of ownership is done, the entity that is giving up ownership is not supposed to do anything further with the memory area since it no longer owns it.
So when you do the malloc() you now own the memory and can use and reuse the memory area as much or as little as you want until such time that you call the free() function to give it back to malloc().
A pointer to a memory region given by malloc() is like any other pointer so far as using it is concerned.
Once you have transferred ownership of a memory area back to malloc() by using thee free() function, you can't call free() again with the same pointer without introducing an error. Once a memory area has been returned using free() you no longer have ownership of the memory so you shouldn't try to do anything else with it and that includes calling free() with the pointer again.
How malloc() manages memory is an implementation detail that will vary depending on the compiler and the C Runtime used. In some cases if you malloc() memory then free() the memory and then malloc() the same amount of memory again you may get lucky and get the same memory area again however it is not something you can count on or should expect.
malloc() provides you a pointer to a memory area that has a couple of guarantees. First of all the memory area provided will be at least as large as you requested. It may be larger but it won't be smaller than what you requested. Secondly the address provided will be on a memory boundary suitable for the machine architecture so that you can use the address provided for any variable type whether a built in such as int or double or a struct or an array of some type.
As the owner of the memory area provided by malloc() you are responsible for giving the memory area back to the malloc() functionality once you are done with it.
Your other primary responsibility is to respect the size of the memory area and to not write a larger data block into the area than the size requested when the malloc() was done. You are guaranteed only the amount of memory requested and writing a larger block of data into the memory will probably overwrite memory that you do not own but is owned by something else.
Unfortunately because the malloc() functionality, at least the optimized or non-debug version of the library, is designed with little as possible overhead, the functionality has few consistency and sanity checks in place. The malloc() functionality trusts that you will obey the rules and guidelines and only use what you own. And often when you break the rules and guidelines, you won't see the effect at the point where you have made a mistake but rather at some other point when some mysterious memory corruption is discovered and your program crashes.
You can use and reuse dynamically allocated memory as long as you have not called free() on it. If you free it and attempt to use it again, then you will have undefined behaviour.
You can continue to reusing memory (eg buf created by char *buf = calloc(sizeOfBuf); ) allocated to you on a single call to calloc(), until free(buf) is called, just as if buf was created statically, eg char buf[sizeOfBuf]; = 0. However, if the size of the buffer initially created by using calloc() needs to change, realloc() is available to do this, and is the preferable method. There are some caveats about using realloc however. Here is an example of using realloc, this one packaged into a function that resizes an existing dynamically allocated buffer, and takes care of some of the caveats:
realloc usage example:
// initial call to calloc
char *buf = calloc(sizeOfBuf);
if(buf)
{
while(someConditionIsTrue)
{
// read new content
//...
//new content needs to be added to buf
char *tmp = realloc(buf, newSizeOfBuffer);
if(!tmp)//if failed...
{
free(buf);//... free original buf to prevent memory loss
return NULL;// return null, caller must test for this
}
buf = tmp;//...else copy new mem location back to original pointer
//continue doing stuff with buf
}
//when done with buf, free it
free(buf);
}
One other suggestion, consider calloc() returns uninitialized memory, i.e. you own a space that contains whatever was occupying it when it was given to you. It is a good idea to follow that command with a method to clean up the buffer:
memset(buf, 0, sizeOfBuf);
Or use calloc().

How to free a char* that is being returned from another function?

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.

Dealing with returning C strings

What is considered better practice when writing methods that return strings in C?
passing in a buffer and size:
void example_m_a(type_a a,char * buff,size_t buff_size)
or making and returning a string of proper size:
char * example_m_b(type_a a)
P.S. what do you think about returning the buffer ptr to allow assignment style and
nested function calls i.e.
char * example_m_a(type_a a,char * buff,size_t buff_size)
{
...
return buff;
}
Passing a buffer as an argument solves most the problems this type of code can run into.
If it returns a pointer to a buffer, then you need to decide how it is allocated and if the caller is responsible for freeing it. The function could return a static pointer that doesn't need to be freed, but then it isn't thread safe.
Passing a buffer and a size is generally less error-prone, especially if the sizes of your strings are typically of a "reasonable" size. If you dynamically allocate memory and return a pointer, the caller is responsible for freeing the memory (and must remember to use the corresponding free function for the memory depending on how the function allocated it).
If you examine large C APIs such as Win32, you will find that virtually all functions that return strings use the first form where the caller passes a buffer and a size. Only in limited circumstances might you find the second form where the function allocates the return value (I can't think of any at the moment).
I'd prefer the second option because it allows the function to decide how big a buffer is needed. Often the caller is not in a position to take that decision.
Another alternative to the pass a buffer and size style, using a return code:
size_t example_m_a(type_a a,char * buff,size_t buff_size)
A zero return code indicates that the caller's buffer was suitable and has been filled in.
A return code > 0 indicates that the caller's buffer was too small and reveals the size that is actually needed, allowing the caller to resize his buffer and retry.
Passing buffer address and length is best in most cases. It is less error-prone and one does not have to worry about memory leaks. In fact, in some tight embedded systems it is completely undesirable to use the heap. However, the function must not overrun the buffer as that can crash the system and worse: make it vulnerable to hackers.
The only time where I've seen function returning allocated buffer is libxml's API to generate XML text from xmlDoc.

Does a string created with 'strcpy' need to be freed?

Does a string created with 'strcpy' need to be freed? And how to free it?
Edit: The destination is allocated like this:
char* buffer[LEN];
strcpy itself doesn't allocate memory for the destination string so, no, it doesn't have to be freed.
Of course, if something else had allocated memory for it, then, yes, that memory should be freed eventually but that has nothing to do with strcpy.
That previous statement seems to be the case since your definition is an array of character pointers rather than an array of characters:
char* buffer[LEN];
and that will almost certainly be done with:
buffer[n] = malloc (length);
It's a good idea to start thinking in terms of responsibility for malloc'ed memory. By that, I mean passing a malloc'ed memory block may also involve passing the responsibility for freeing it at some point.
You just need to figure out (or decide, if it's your code) whether the responsibility for managing the memory goes along with the memory itself. With strcpy, even if you pass in an already-malloc'ed block for the destination, the responsibility is not being passed so you will still have to free that memory yourself. This allows you to easily pass in a malloc'ed or non-malloc'ed buffer without having to worry about it.
You may be thinking of strdup which is basically making a copy of a string by first allocating the memory for it. The string returned from that needs to be freed, definitely.
If you use
char buffer[6];
strcpy(buffer, "hello");
for example, then buffer is freed when the end of its scope is reached.
On the other hand,
char *buffer;
buffer = malloc(sizeof(char) * 6);
strcpy(buffer, "hello");
this way you need to free the memory you allocated.
But it doesn't actually have anything to do with strcpy, only about how you allocate your string.
You provide a pointer to the destination buffer for strcpy, so it depends on how you allocated that buffer as to whether it needs to be freed and how to free it.
For example if you allocated the buffer using malloc, then yes you will need to free it. If you allocated the buffer on the stack then no you will not, it will be released automatically when it goes out of scope.
The strcpy function copies a string into a buffer you need to get some other way (such as malloc); you should free that buffer using whatever mechanism is correct for how you allocated it.
strcpy() doesn't create a string, it only copies a string. Memory allocation is completely separated from that process.
So you have to take care of memory to which the string is copied - if it was allocated dynamically you have to free it at some point. Since you seem to have a stack-allocated buffer you don't have to do anything special - the buffer will be reclaimed when it goes out of scope.

C when to allocate and free memory - before function call, after function call...etc

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.

Resources