开发者

Memory allocated with malloc does not persist outside function scope?

Hi,

I'm a bit new to C's malloc function, but from what I know it should store the value in the heap, so you can reference it with a pointer from outside the original scop开发者_如何学Ce. I created a test program that is supposed to do this but I keep getting the value 0, after running the program. What am I doing wrong?

#include <stdio.h>
#include <stdlib.h>

int f1(int *b) {
    b = malloc(sizeof(int));
    *b = 5;
}

int main(void) {
    int *a;
    f1(a);
    printf("%d\n", a);
    return 0;
}


Yes! a is passed by value so the pointer b in function f1 will be local.. either return b,

int *f1() {
    int * b = malloc(sizeof(int));
    *b = 5;
    return b;
}

int main() {
    int * a;
    a = f1();
    printf("%d\n", *a);
    // keep it clean : 
    free(a);
    return 0;
}

or pass a's address

int f1(int ** b) {
    *b = malloc(sizeof(int)); 
    **b = 5;
}

int main() {
    int * a;
    f1(&a);
    printf("%d\n", *a);
    // keep it clean : 
    free(a);
    return 0;
}


It looks like you're misunderstanding a fundamental part of how C works - namely that it is a 'pass-by-value' language. In order for main() to know about the memory you allocated, you have to get it back out. The following code will do you what you want:

int f1(int **b)
{
    *b = malloc(sizeof(int));
    **b = 5;
}

int main(int argc, char **argv)
{
    int *a;
    f1(&a);
    printf("%d\n", *a);
    return 0;
}

There are a couple differences between this code and yours; first, the signature of f1() has changed, so that it can return the result of the malloc() call in the passed in pointer. Next, the call to f1() has been changed to pass the address of a rather than a itself - important if you want it to be 'filled-in' by f1(), so to speak. Finally, the printf() in main() has been changed to print out the pointed-to value rather than the pointer itself.


The memory itself persists, but it leaks because you're not providing the allocated pointer to the caller. Also, you're printing a when you should be printing *a. Finally, you're not returning an int from f1.

Try:

void f1(int **b) {
 *b = malloc(sizeof(int));
 **b = 5;
}

int main() {
 int *a;
 f1(&a);
 printf("%d\n", *a);
 free(a);
 return 0;
}


Lets suppose you assign a value of NULL to a before you call function f1. Now the way f1 is defined it takes its argument(pointer to an int) by value. That is b will be another variable of type int * which will be a copy of a. So b too will have a value of NULL. Now in f1 you change the value by b by assigning it the address of memory allocated dynamically using malloc. Lets say that memory address is 0x123. As a result of this assignment, b has changed its value from NULL to 0x123 but a(in main) continues to hold NULL, because changing b will not change a, as they are two separate variables. As a result of this when you return from function f1 a will remain unchanged.

There are 2 ways to solve this. One you can make the function f1 return the value of the changed b and then assign it back to a in main and two, you can pass the a by address so that any changes made in f1 will affect a in main too.

// f1 now returns the value of b.
int* f1() {
 int *b = malloc(sizeof(int));
 *b = 5;
 return b;
}

int main() {
 int *a = NULL;
 a = f1(); // assign the return value of f1 to a.
 printf("%d\n", *a); // prints 5...not its *a not just a.
 return 0;
}

.

// f1 now takes the address of a. 
void f1(int **b) {
 *b = malloc(sizeof(int)); // you are actually altering a indirectly.
 **b = 5; 
}

int main() {
 int *a = NULL;
 f1(&a); // now pass the address of a to f1.
 printf("%d\n", *a); // prints 5...not its *a not just a.
 return 0;
}


The address int *b is deleted when the function return. To save it, you need to use a pointer of a pointer

int f1(int ** b) {
   *b = malloc(sizeof(int));
   **b = 5;
}


Your problem is actually not related to malloc, but rather the fact that you're passing the value the pointer currently holds, rather than the address of it. Try the following:

int f1(int ** b) {
    *b = malloc(sizeof(int)); 
    **b = 5;
}

int main() {
    int * a;
    f1(&a);
    printf("%d\n", *a);
    return 0;
}

By passing the pointer value as you were, there was no way for the value malloc created to be stored into the pointer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜