tags:

views:

246

answers:

8

Hi, does this code

char *a()
{
    char *t = malloc(8);
    t[0] = 'a'; 
    t[1] = 'b';
    ...
    t[7] = 'h';
    return t;
}
int main(void)
{
    char *x = a();
    //do something with x 
    .....
    free(x);
    return 0;
}

have any potential problems since I allocate memory in a() and use that memory in main()??

Thanks.

A: 

No you won't have any problems explicitly because you allocated the function in a and use it in main.

theycallmemorty
+1  A: 
Adam Liss
+1 even though you missed the problem of returning values from `void a()` (I almost missed it too, and @Ed beat us all to the punch).
Chris Lutz
Ack - good catch!
Adam Liss
A: 

As long as you remember to free the memory that x points to then you won't have any problems. By using malloc() you've allocated memory on the heap which is left alone when returning to the calling function.

mash
+10  A: 

First, a() is declared as returning void, but you attempt to return a char*. Change the signature to return a char*.

Second, your function is fine, but your example code has a memory leak because you never free the memory that the returned pointer points to.

Third, as gbrandt pointed out, you are not checking for success after the call to malloc. malloc can fail, and checking to see if it did is a good habit to get into.


Another way to accomplish this would be to pass a pointer to a pointer into a() instead, and then the caller has to create the pointer themselves before passing it to a(), but either way you still need to free the memory. To be honest, I would go with your approach over this in this case. There is no compelling reason to do it this way, just thought I would mention it.

void a(char **p)
{
    *p = malloc(8);
    if (*p)
    {
        **p[0] = 'a'; 
        **p[1] = 'b';
        ...
        **p[7] = 'h';
    }
}

int main(void)
{
    char *x;
    a(&x);
    //do something with x 
    .....
    free(x);
}

If this alternate approach confuses you, please let me know as I would be happy to provide an explanation (though, at the moment, I need to get back to work!)

Ed Swangren
+1 for beating me to the punch with the returning from a `void` function, but seriously, why not just have `a` return a `char *`? It would be so much easier (and less confusing to someone new to C like I suspect the OP may be).
Chris Lutz
Yes, I wasn't sure if I should include that part at all. I edited the post to say that the original way is ok, and here is an alternate way to accomplish the same thing.
Ed Swangren
+1  A: 

Apart from having the wrong return type on a() (should be char * instead of void), the code doesn't have any problems.

Just be sure to free() the memory you allocated when you're done with it.

John Bode
+3  A: 

All good advice above. Small problems with the code, the big one is...

You are not checking for success in the malloc or after the function call. Never forget error handling.

gbrandt
+1 because I also forgot about error handling.
Chris Lutz
Actually there *is* some problem with the code (wrong return type) but +1 for checking the malloc'ed memory.
Francesco
+1 because I also forgot to check what malloc returned.
Ed Swangren
+1  A: 

Most of the answers here indicate that this isn't a problem, just remember to free() it later. This is technically true, but is really a problem. Any time you allocate memory in one scope and expect it to be freed in another, you are asking for a memory leak. People don't remember to free the memory. There is also the problem that the caller will have to know that you used malloc and not alloca() or new() or something else. If they call anything but the matched deallocation routine, the results are undefined.

In short, it is usually a mistake to allocate memory and pass it back to the caller.

It is better to expect the memory to be allocated by the caller because if they allocate it, they will remember to free it and to do so correctly.

Steve Rowe
This isn't a problem with the OP's code, it's a problem with the OP's code's (imaginary) users. If you're a C programmer, you remember to `free()` memory. Period. Anyone who doesn't understand memory management and doesn't read the documentation on what memory they need to `free()` when they're done doesn't know C.
Chris Lutz
Yes, I agree Chris. This is C, not C++.
Ed Swangren
@Ed - Ouch. That's kind of harsh on C++ programmers. Not saying it's not necessarily true...
Chris Lutz
I disagree. My arguments apply equally to C. Alloca is a C allocator. CoMemAlloc is a C allocator. There are plenty of others as well.
Steve Rowe
A: 

Thanks. I just edited the code. I guess this time it should have no problem. Btw, in C, when a function finishes, does the compiler clear all variables (including array & pointer) in the stack?

If it's a local variable in the function, it will be gone from the stack when the function returns. But if you allocated it on the heap (ala malloc() or such), though the pointer pointing to it will be lost with the stack frame, the memory allocated will persist if you didn't free() it before returning. Of course, in this example, since you're returning a pointer to it, the calling function can keep a handle on the memory.
Doug Kavendek