tags:

views:

327

answers:

6

I was just wondering, in the following scenarion, is the memory used by 'stringvar' freed after method1 is done executing?

// Just some method
void method2(char* str)
{
  // Allocate 10 characters for str
  str = malloc(10 * sizeof(char));
}

// Just another method
void method1()
{
  char* stringvar;
  method2(stringvar);

  // Is the memory freed hereafter, or do I need to call free()?
}

I ask, because if I put a 'free(stringvar)' at the end of method1, I get a warning that stringvar is unitialized inside method1 (which is true).

A: 

No, you'll need to call free() on it yourself. Try putting char *stringvar = 0; to suppress the warning.

kitchen
A: 

You must use free()

Szczepan
+20  A: 

No, the memory is not deallocated after method1, so you'll have a memory leak. Yes, you will need to call free after you're done using the memory.

You need to send a pointer to a pointer to method2 if you want it to allocate memory. This is a common idiom in C programming, especially when the return value of a function is reserved for integer status codes. For instance,

void method2(char **str) {
    *str = (char *)malloc(10);
}

char *stringvar;
method2(&stringvar);
free(stringvar);
Andrew Keeton
Thank you for pointing out the rather serious bug in method2.
emk
You should not cast the return value of malloc, since this is C.
aib
If I want to address the "str" in method2 as an array, I would have to use *str[x], right?
pbean
@pbean Yes. Because `str` is a pointer to a pointer to `char`, you have to dereference it first before it's any useful. `*str` is a single pointer to `char`, and in this case it happens to represent a string. So yes, `*str[x]` will get you the xth character of the string pointed to by `*str`. However, outside of `method2` you already have a pointer to `char`, so say `stringvar[x]` would suffice.
Andrew Keeton
@aib I like to cast the results from `malloc` for two reasons: 1) When dealing with double pointers and such, having the "return type" of `malloc` right there helps me when I'm glancing at it, and 2) if I get my pointers wrong (say I said `str =` instead of `*str =`) then the compiler will let me know. I know about http://c-faq.com/malloc/mallocnocast.html, but I always compile on high warnings, so I would notice if I didn't include `malloc`.
Andrew Keeton
+2  A: 

Not only is stringvar uninitialized inside method1, but allocating memory for it inside method2 the way you are doing is faulty. You change the copy of the pointer inside method2, but this does not affect the copy of the pointer in method1. You would need to use a double-pointer in order for stringvar in method1 to point to the memory allocated by method2.

Nick Meyer
+5  A: 

No, dynamically allocated memory is not automatically freed for you. In C it's the programmers responsibility to free.

Also - C passes variables by values, str = malloc(10 * sizeof(char)); just assigns to the local 'str' variable.

Seems like you'd want to return the pointer obtained from malloc, so your program becomes:

char *method2(void)
{
  // Allocate 10 characters for str
  return malloc(10 * sizeof(char));
}

// Just another method
void method1()
{
  char* stringvar;
  stringvar = method2();
  ...
  free(stringvar);
}

The other option, if you want to manipulate 'stringvar' from within method2 is to pass a pointer to 'stringvar', e.g.

void method2(char** str)
{
  // Allocate 10 characters for str
  *str = malloc(10 * sizeof(char));
}

// Just another method
void method1()
{
  char* stringvar;
  method2(&stringvar);
  ...
  free(stringvar);
}
nos
Don't forget to put in the calls to free()
plinth
For what it's worth, `sizeof(char)` is guaranteed to be 1 by the standard, so you don't need to multiply by it. I doubt it matters, but I think it looks a little cleaner without.
Chris Lutz