I'm currently trying to find out the best way to program functionally in C, but I'm having a problem in freeing the memory after being allocated.
consider the following example: (I deleted the unimportant parts because I thought it would be too long)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* someFunction(int someParam)
{
//... some code ...
char* str = malloc((strlen)*sizeof(char));
//... some code ...
return(str);
}
int main()
{
//... some code ...
printf("%s\n", someFunction(someParam))
return 0;
}
Here, since someFunction is called inside printf, and there seems to be no way to free the memory that's been allocated for the string. Note that this code DOES compile with GCC, but I'm looking for a way to reduce the memory load overall.
I could define a temporary variable and free it later in the main function, but the code would be more difficult to read as the functions get nested more.
You need to use a temporary variable so you can free it later. Otherwise you'll have a memory leak each time you call the function like this.
C doesn't have any form of automatic memory management, except that most operating systems will reclaim all of the process's private memory when it terminates. Unfortunately, this means that your program will need to be a little more verbose.
If you really want to have that functional style, you can pass an additional (pointer) argument where you record whatever needs to be cleaned up:
char* someFunction(int someParam, void **cleanup)
{
//... some code ...
char* str = malloc((strlen)*sizeof(char));
//... some code ...
*cleanup = str;
return(str);
}
int main()
{
void *cleanup = 0;
//... some code ...
printf("%s\n", someFunction(someParam, &cleanup));
free(cleanup);
return 0;
}
If you want to extend this, you can replace the simple void * with a data structure that can record multiple pointers that need later cleanup, and add multiple allocated things to it, and then clean them up all at once at the end.
Simply allocate the buffer in main and pass it as a parameter to the function so that it may populate it.
This way you don't have to have global variables.
//... some code ...
int someFunction(int someParam, char *output, int somesize)
{
//... some code ...
// update a maximum of 'somesize' of output
snprintf(output, somesize, "some special string");
//... some code ...
return strlen("some special string");
}
int main()
{
char buffer[somesize]; // or use malloc and free at the end
//... some code ...
if (someFunction(someParam, buffer, somesize) > 0) {
printf("%s\n", buffer);
}
return 0;
}
Related
I wrote some code in C and I need to handle the situation that fail to malloc() or realloc(). I know that if memory allocation failed, it will return NULL, and I wrote something as follow:
char *str = (char *)malloc(sizeof(char));
if (str == NULL)
{
puts("Malloc Failed.");
// do something
}
// do something else
So the problem is, how can I test this part of code?
It is impossible to run out of my memory on my machine by hand. So I want to restrict the biggest memory size it can use.
Can I specify the maximum memory size my program can use when I compile/run it? Or is there any technique to do it?
For your information, I write code in standard C, compile it with gcc, and run it on Linux environment.
Many thanks in advance.
You can create a test file that essentially overrides malloc.
First, use a macro to redefine malloc to a stub function, for example my_malloc. Then include the source file you want to test. This causes calls to malloc to be replaced with my_malloc which can return whatever you want. Then you can call the function to test.
#include <stdio.h>
#include <stdlib.h>
#define malloc(x) my_malloc(x)
#include "file_to_test.c"
#undef malloc
int m_null;
void *my_malloc(size_t n)
{
return m_null ? NULL : malloc(n);
}
int main()
{
// test null case
m_null = 1;
function_to_test();
// test non-null case
m_null = 0;
function_to_test();
return 0;
}
you can simply give malloc a big number to allocate and it will fail to allocate the size you trying to.
I would like to do something like that :
#include <stdio.h>
char * myfunction(char * in);
void myfunction2(char * in, const char ** content);
int main(){
char * name="aName";
char * result = myfunction(name);
return 0;
}
char * myfunction(char * in) {
const char *test = NULL;
myfunction2(in, &test);
return test; // I would like to return the value of test
}
void myfunction2(char * in, const char ** content) {
char input[1024];
//do some stuff to fill input
*content = input;
}
But I'm not able to do it, some weird char are printed instead sometimes...
Thank you for your reply, I understand it well now, but I'm stuck on another side of my problem. I didn't write precisely my use case, so I edited it to be complete.
The most glaring things wrong in this code are:
Implicit declaration of myfunction as int myfunction();
Incorrect const-ness of your pointers.
No return value provided for main()
Implicit declaration of myfunction as int myfunction();
This is easy enough to solve, and your compiler should be barking loudly at you when this happens. As a legacy feature of C, when a function call is encountered where no formal declaration, either by prototype or definition, is known, the function is assumed to return int and accept a variable number of parameters. Therefore in main() your call is assumed to be to a function that looks like this:
int myfunction();
Later when the real myfunction is encountered, at a minimum your compiler should scream at you with warning about how the declaration doesn't match the expected type (because by this time it thinks it is int myfunction()). Even then, however, the call should still go through, but it is terrible practice to rely on this. Properly prototype your functions before use.
Incorrect data types for all your pointers.
The string literal in your function is not bound to local array space. It is a read-only data buffer sitting in a read-only segment somewhere in your program's data blocks. The correct declaration is this:
const char *test = "mytest";
but that has the ripple effect of requiring changes to the rest of this code, which you'll see in a moment.
No return value provided for main()
Be definitive in your conclusion of main(). Apparently C99 allows you to skip this and implementation is supposed to return 0 for you. Don't give them that joy; seize it yourself.
Addressing all of the above...
#include <stdio.h>
void myfunction(const char** in);
int main()
{
const char *result = NULL;
myfunction(&result);
printf("in main() %p : %s\n", result, result);
return 0;
}
void myfunction(const char** in)
{
const char* test = "mytest";
printf("in myfunction() %p : %s\n", test, test);
*in = test;
}
Output (varies by implementation)
in main() 0x8048580 : mytest
in myfunction() 0x8048580 : mytest
See it live.
It looks good to me. May I suggest giving it a prototype or moving your myfunc() definition before main(). Also assigning a value to result when it is declared. That will give you a better idea of what is going on if the function is not doing what you expect.
For some reason, the other answers just pointed out technical detail that's wrong, but failed to notice what is really wrong: You are returning the address of an array on the stack. But when the function returns, accessing that array becomes undefined behavior. Other code may freely overwrite the memory, leaving the worst possible garbage in it, or, conversely, writing to the memory behind the returned pointer may trash any vitally important variable of some other, entirely unconnected parts of the code.
If you want to return a pointer, you must either return a pointer to a static object, or you must return a pointer to something on the heap. Here is the static case:
char* foo() {
static char staticArray[1024];
return staticArray;
}
Using static here guarantees that the memory reserved for staticArray[] will remain reserved for it throughout the execution of your program. There are, however, three downsides of this:
the array size is fixed at compile time
this is generally not multithreading safe since all threads will use the same globally allocated memory
you generally cannot expect the data behind the returned pointer to remain intact across a function call. Consider this code:
void bar() {
char* temp = foo();
temp[0] = 7;
}
void baz() {
char* temp = foo();
temp[0] = 3;
bar();
//now temp[0] is 7 !
}
This might be desirable in some rare cases, however, in most it's not.
So, if you want to be able to freely use the memory behind the returned pointer, you have to malloc() memory for it (and free() it afterwards, of course). Like this:
char* foo(int size) {
return malloc(size);
}
void baz() {
char* sevenBytes = foo(7);
//Do something with seven bytes
free(sevenBytes);
}
void bar() {
char* threeBytes = foo(3);
threeBytes[0] = 3;
baz();
assert(threeBytes[0] == 3); //baz() worked on it's own memory
free(threeBytes);
}
In the case of string handling, there is a number of handy functions available in the POSIX-2008 standard that do the memory allocation for you, among them strdup() and asprintf(). Here are some usage examples:
int main() {
char* hello = strdup("Hello");
char* greeting;
if(0 > asprintf(&greeting, "%s World!\nMemory for hello was allocated at %llx", hello, (long long)hello)) {
//error handling
}
printf(greeting);
free(hello);
free(greeting);
}
This will print something like:
Hello World!
Memory for hello was allocated at c726de80
I'm not an expert in C, but here's what I'm trying to do:
int main(void) {
double *myArray;
...
myFunction(myArray);
...
/* save myArray contents to file */
...
free(myArray);
...
return 0;
}
int myFunction(double *myArray) {
int len=0;
...
/* compute len */
...
myArray = malloc( sizeof(double) * len );
if (myArray == NULL)
exit(1);
...
/* populate myArray */
...
return 0;
}
I'd like to save the contents of myArray inside main, but I don't know the size required until the program is inside myFunction.
Since I'm using CentOS 6.2 Linux, which I could only find a gcc build available up to 4.4.6 (which doesn't support C99 feature of declaring a variable-length array; see "broken" under "Variable-length arrays in http://gcc.gnu.org/gcc-4.4/c99status.html), I'm stuck using -std=c89 to compile.
Simple answer is no.
You are not passing back the pointer.
use
int main(void) {
double *myArray;
...
myFunction(&myArray);
...
/* save myArray contents to file */
...
free(myArray);
...
return 0;
}
int myFunction(double **myArray) {
int len=0;
...
/* compute len */
...
*myArray = malloc( sizeof(double) * len );
if (NULL == *myArray)
exit(1);
...
EDIT
poputateThis = *myArray;
/* populate poputateThis */
END OF EDIT
...
return 0;
EDIT
Should simplify thigs for your
}
What you are doing is not OK since myFunction doesn't change the value myArray holds in main; it merely changes its own copy.
Other than that, it's OK even if stylistically debatable.
As a question of good design and practice (apart from syntax issues pointed out in other answers) this is okay as long as it is consistent with your code base's best practices and transparent. Your function should be documented so that the caller knows it has to free and furthermore knows not to allocate its own memory. Furthermore consider making an abstract data type such as:
// myarray.h
struct myarray_t;
int myarray_init(myarray_t* array); //int for return code
int myarray_cleanup(myarray_t* array); // will clean up
myarray_t will hold a dynamic pointer that will be encapsulated from the calling function, although in the init and cleanup functions it will respectively allocate and deallocate.
What you want to do is fine, but your code doesn't do it -- main never gets to see the allocated memory. The parameter myArray of myFunction is initialized with the value passed in the function call, but modifying it thereafter doesn't modify the otherwise-unrelated variable of the same name in main.
It appears in your code snippet that myFunction always returns 0. If so then the most obvious way to fix your code is to return myArray instead (and take no parameter). Then the call in main would look like myArray = myFunction();.
If myFunction in fact already uses its return value then you can pass in a pointer to double*, and write the address to the referand of that pointer. This is what Ed Heal's answer does. The double ** parameter is often called an "out-param", since it's a pointer to a location that the function uses to store its output. In this case, the output is the address of the buffer.
An alternative would be to do something like this:
size_t myFunction(double *myArray, size_t buf_len) {
int len=0;
...
/* compute len */
...
if (buf_len < len) {
return len;
}
/* populate myArray */
...
return len;
}
Then the callers have the freedom to allocate memory any way they like. Typical calling code might look like this:
size_t len = myFunction(NULL, 0);
// warning -- watch the case where len == 0, if that is possible
double *myArray = malloc(len * sizeof(*myArray));
if (!myArray) exit(1);
myFunction(myArray, len);
...
free(myArray);
What you've gained is that the caller can allocate the memory from anywhere that's convenient. What you've lost is that the caller has to write more code.
For an example of how to use that freedom, a caller could write:
#define SMALLSIZE 10;
void one_of_several_jobs() {
// doesn't usually require much space, occasionally does
double smallbuf[SMALLSIZE];
double *buf = 0;
size_t len = myFunction(smallbuf, SMALLSIZE);
if (len > SMALLSIZE) {
double *buf = malloc(len * sizeof(*buf));
if (!buf) {
puts("this job is too big, skipping it and moving to the next one");
return;
}
} else {
buf = smallbuf;
}
// use buf and len for something
...
if (buf != smallbuf) free(buf);
}
It's usually an unnecessary optimization to avoid a malloc in the common case where only a small buffer is needed -- this is only one example of why the caller might want a say in how the memory is allocated. A more pressing reason might be that your function is compiled into a different dll from the caller's function, perhaps using a different compiler, and the two don't use compatible implementations of malloc/free.
I have argument with my friend. He says that I can return a pointer to local data from a function. This is not what I have learned but I can't find a counterargument for him to prove my knowledge.
Here is illustrated case:
char *name() {
char n[10] = "bodacydo!";
return n;
}
And it's used as:
int main() {
char *n = name();
printf("%s\n", n);
}
He says this is perfectly OK because after a program calls name, it returns a pointer to n, and right after that it just prints it. Nothing else happens in the program meanwhile, because it's single threaded and execution is serial.
I can't find a counter-argument. I would never write code like that, but he's stubborn and says this is completely ok. If I was his boss, I would fire him for being a stubborn idiot, but I can't find a counter argument.
Another example:
int *number() {
int n = 5;
return &n;
}
int main() {
int *a = number();
int b = 9;
int c = *a * b;
printf("%d\n", c);
}
I will send him this link after I get some good answers, so he at least learns something.
Your friend is wrong.
name is returning a pointer to the call stack. Once you invoke printf, there's no telling how that stack will be overwritten before the data at the pointer is accessed. It may work on his compiler and machine, but it won't work on all of them.
Your friend claims that after name returns, "nothing happens except printing it". printf is itself another function call, with who knows how much complexity inside it. A great deal is happening before the data is printed.
Also, code is never finished, it will be amended and added to. Code the "does nothing" now will do something once it's changed, and your closely-reasoned trick will fall apart.
Returning a pointer to local data is a recipe for disaster.
you will get a problem, when you call another function between name() and printf(), which itself uses the stack
char *fun(char *what) {
char res[10];
strncpy(res, what, 9);
return res;
}
main() {
char *r1 = fun("bla");
char *r2 = fun("blubber");
printf("'%s' is bla and '%s' is blubber", r1, r2);
}
As soon as the scope of the function ends i.e after the closing brace } of function, memory allocated(on stack) for all the local variables will be left. So, returning pointer to some memory which is no longer valid invokes undefined behavior.
Also you can say that local variable lifetime is ended when the function finished execution.
Also more details you can read HERE.
My counter-arguments would be:
it's never OK to write code with undefined behavior,
how long before somebody else uses that function in different context,
the language provides facilities to do the same thing legally (and possibly more efficiently)
It's undefined behavior and the value could easily be destroyed before it is actually printed. printf(), which is just a normal function, could use some local variables or call other functions before the string is actually printed. Since these actions use the stack they could easily corrupt the value.
If the code happens to print the correct value depends on the implementation of printf() and how function calls work on the compiler/platform you are using (which parameters/addresses/variables are put where on the stack,...). Even if the code happens to "work" on your machine with certain compiler settings it's far from sure that it will work anywhere else or under slightly different border conditions.
You are correct - n lives on the stack and so could go away as soon as the function returns.
Your friend's code might work only because the memory location that n is pointing to has not been corrupted (yet!).
As the others have already pointed out it is not illegal to do this, but a bad idea because the returned data resides on the non-used part of the stack and may get overridden at any time by other function calls.
Here is a counter-example that crashes on my system if compiled with optimizations turned on:
char * name ()
{
char n[] = "Hello World";
return n;
}
void test (char * arg)
{
// msg and arg will reside roughly at the same memory location.
// so changing msg will change arg as well:
char msg[100];
// this will override whatever arg points to.
strcpy (msg, "Logging: ");
// here we access the overridden data. A bad idea!
strcat (msg, arg);
strcat (msg, "\n");
printf (msg);
}
int main ()
{
char * n = name();
test (n);
return 0;
}
gcc : main.c: In function ‘name’:
main.c:4: warning: function returns address of local variable
Wherever it could been done like that (but it's not sexy code :p) :
char *name()
{
static char n[10] = "bodacydo!";
return n;
}
int main()
{
char *n = name();
printf("%s\n", n);
}
Warning it's not thread safe.
You're right, your friend is wrong. Here's a simple counterexample:
char *n = name();
printf("(%d): %s\n", 1, n);
Returning pointer to local variable is aways wrong, even if it appears to work in some rare situation.
A local (automatic) variable can be allocated either from stack or from registers.
If it is allocated from stack, it will be overwritten as soon as next function call (such as printf) is executed or if an interrupt occurs.
If the variable is allocated from a register, it is not even possible to have a pointer pointing to it.
Even if the application is "single threaded", the interrupts may use the stack. In order to be relatively safe, you should disable the interrupts. But it is not possible to disable the NMI (Non Maskable Interrupt), so you can never be safe.
While it is true that you cannot return pointers to local stack variables declared inside a function, you can however allocate memory inside a function using malloc and then return a pointer to that block. Maybe this is what your friend meant?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* getstr(){
char* ret=malloc(sizeof(char)*15);
strcpy(ret,"Hello World");
return ret;
}
int main(){
char* answer=getstr();
printf("%s\n", answer);
free(answer);
return 0;
}
The way I see it you have three main options because this one is dangerous and utilizes undefined behavior:
replace: char n[10] = "bodacydo!"
with: static char n[10] = "bodacydo!"
This will give undesirable results if you use the same function more than once in row while trying to maintain the values contained therein.
replace:
char n[10] = "bodacydo!"
with:
char *n = new char[10];
*n = "bodacydo!"
With will fix the aforementioned problem, but you will then need to delete the heap memory or start incurring memory leaks.
Or finally:
replace: char n[10] = "bodacydo!";
with: shared_ptr<char> n(new char[10]) = "bodacydo!";
Which relieves you from having to delete the heap memory, but you will then have change the return type and the char *n in main to a shared_prt as well in order to hand off the management of the pointer. If you don't hand it off, the scope of the shared_ptr will end and the value stored in the pointer gets set to NULL.
If we take the code segment u gave....
char *name() {
char n[10] = "bodacydo!";
return n;
}
int main() {
char *n = name();
printf("%s\n", n);
}
Its okay to use that local var in printf() in main 'coz here we are using a string literal which again isn't something local to name().
But now lets look at a slightly different code
class SomeClass {
int *i;
public:
SomeClass() {
i = new int();
*i = 23;
}
~SomeClass() {
delete i;
i = NULL;
}
void print() {
printf("%d", *i);
}
};
SomeClass *name() {
SomeClass s;
return &s;
}
int main() {
SomeClass *n = name();
n->print();
}
In this case when the name() function returns SomeClass destructor would be called and the member var i would have be deallocated and set to NULL.
So when we call print() in main even though since the mem pointed by n isn't overwritten (i am assuming that) the print call will crash when it tried to de-reference a NULL pointer.
So in a way ur code segment will most likely not fail but will most likely fail if the objects deconstructor is doing some resource deinitialization and we are using it afterwards.
Hope it helps
I have a structure defined like so:
typedef struct {
int n;
int *n_p;
void **list_pp;
size_t rec_size;
int n_buffs;
size_t buff_size
} fl_hdr_type;
and in my code I Have a function for initlialization that has the following
fl_hdr_type *fl_hdr;
fl_hdr = malloc(sizeof(fl_hdr_type) + (buff_size_n * rec_size_n));
where those buffer size are passed in to the function to allow space for the buffers as well.
The size is pretty small typically..100*50 or something like that..plenty of memory on this system to allocate it.
I can't actually post the stack trace because this code is on another network, but some information pulled from dbx on the core file:
buff_size_n = 32, rec_size_n = 186
and the stack..line numbers from malloc.c
t_splay:861
t_delete:796
realfree: 531
cleanfree:945
_malloc:230
_malloc:186
Any ideas why this fails?
Try running your program through valgrind, see what it reports. It's possible in some other part of the program you have corrupted free lists or something else malloc looks at.
What you need to do is simply do this.
fl_hdr = malloc(sizeof(fl_hdr_type));
The list_pp is a dynamic array of void* and you need to allocate that to the size you need with another malloc.
list_pp is simply a pointer to something else that is allocated on then heap.
If you want to allocate in place with one malloc, then you will need to define it as an array of the actual types you want. The compiler needs to know the types to be able to perform the allocation.
If what you are looking for is dynamic arrays in C, then look at this.
You need to explicitly assign n_p and list_pp to the appropriate offsets.
fl_hdr_type *fl_hdr;
fl_hdr = malloc(sizeof(fl_hdr_type) + (buff_size_n * rec_size_n));
fl_hdr->n_p = fl_hdr+sizeof(fl_hdr_type);
fl_hdr->list_pp = fl_hdr->n_p + (num_n * sizeof(int));
If you're going to do this, I'd recommend putting the pointers at the end of the struct, instead of the middle. I'm with Romain, though, and recommend you use separate calls to malloc() instead of grabbing everything with one call.
I made your example into a program, and have absolutely no issues running it. If you can compile and run this simple code (and it works), you have corrupted the heap somewhere else in your program. Please run it through Valgrind (edit as User275455 suggested, I did not notice the reply) and update your question with the output that it gives you.
Edit
Additionally, please update your question to indicate exactly what you are doing with **list_pp and *n_p after allocating the structure. If you don't have access to valgrind, at least paste the entire trace that glibc printed when the program crashed.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int n;
int *n_p;
void **list_pp;
size_t rec_size;
int n_buffs;
size_t buff_size;
} fl_hdr_type;
static size_t buff_size_n = 50;
static size_t rec_size_n = 100;
static fl_hdr_type *my_init(void)
{
fl_hdr_type *fl_hdr = NULL;
fl_hdr = malloc(sizeof(fl_hdr_type) + (buff_size_n * rec_size_n));
return fl_hdr;
}
int main(void)
{
fl_hdr_type *t = NULL;
t = my_init();
printf("Malloc %s\n", t == NULL ? "Failed" : "Worked");
if (t != NULL)
free(t);
return 0;
}