2010-03-25 51 views
11

分配malloc的内存不会在函数范围外持久存储吗?

嗨,

我有点新的C的malloc函数,但是从我知道它应该值存储在堆,这样你就可以从原来的范围之外的指针引用它。我创建了一个应该这样做的测试程序,但在运行该程序后我一直得到值0。我究竟做错了什么?

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

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

回答

6

内存本身仍然存在,但它泄漏,因为你没有提供所分配的指针调用者。另外,当您应该打印*a时,您正在打印a。最后,你不是从f1返回一个int。

尝试:

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

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

你的问题实际上是不相关的malloc,而是你传递指针目前持有的价值,而不是它的地址的事实。请尝试以下操作:

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

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

通过传递指针值,您无法将创建的malloc值存储到指针中。

+3

这再次通过价值。你传递一个值的地址。 ** C ** – raj 2010-03-25 05:35:46

+0

没有通过引用传球。更新为在C中更准确。 – Dusty 2010-03-25 12:50:07

0

当函数返回时,地址int *b被删除。要保存它,你需要使用一个指针

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

它看起来像你的误解ç是如何工作的一个基本组成部分的指针 - 即它是一个“传址值的语言。为了让main()知道您分配的内存,您必须将其重新取出。以下代码会为你做什么:

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; 
} 

这段代码和你的代码有几点区别,首先,f1()的签名已经更改,以便它可以返回malloc()调用的结果在传入的指针中。接下来,拨打f1()已更改为通过a而不是a本身的地址 - 这一点很重要,如果您希望它由f1()“填充”,可以这么说。最后,printf()main()已被更改为打印出指向的值而不是指针本身。

+7

我不知道为什么每个人都直接跳到使用指针指针 - 这不是解释如何做到这一点的最好方式,以帮助那些遇到更多问题的人语言的基本部分。为什么不直接从'f1()'返回指针呢? – caf 2010-03-25 05:29:08

+0

@caf,是的!对初学者来说这很简单。 – raj 2010-03-25 05:31:27

+0

非常感谢大家的反馈!我的代码现在可用。 我不能让函数返回指针,因为我的实际项目中的函数已经返回其他东西了。 再次感谢! – 2010-03-25 05:40:55

22

是的! a按值传递所以在功能f1指针b将是本地.. 要么返回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; 
} 

或通过a的地址

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; 
} 
5

让我们假设你分配一个值的NULL到之前你调用函数f1。现在f1被定义的方式是它的参数(指向int的值)。那就是b将是int *类型的另一个变量,它将是拷贝a。因此b也将具有值NULL。现在在f1中,通过为其分配使用malloc动态分配的内存地址,将值更改为b。可以说,内存地址是0x123。作为此作业的结果,b已将其值从NULL更改为0x123,但a(在main中)继续保留NULL,因为更改b将不会更改a,因为它们是两个单独的变量。因此,当您从功能f1返回时,a将保持不变。

有两种方法可以解决这个问题。您可以使功能f1返回已更改的b的值,然后将其分配回main中的一个和两个,您可以传递该地址以便在f1中进行的任何更改也会影响main中的一个。

// 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; 
}