使用malloc分配的内存不会在函数范围之外保留?

时间:2010-03-25 05:16:08

标签: c malloc

您好,

我对C的malloc函数有点新,但据我所知,它应该将值存储在堆中,因此您可以使用来自原始范围之外的指针来引用它。我创建了一个应该执行此操作的测试程序,但在运行程序后,我一直得到值0。我做错了什么?

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

6 个答案:

答案 0 :(得分:24)

是的! a 按值传递,因此函数b中的指针f1将是本地的.. 要么返回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;
}

答案 1 :(得分:9)

看起来你误解了C的工作方式的一个基本部分 - 即它是一种“按价值传递”的语言。为了让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()已更改为打印出指向的值而不是指针本身。

答案 2 :(得分: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;
}

答案 3 :(得分:5)

让我们假设您在调用函数NULL之前为其分配值f1。现在定义f1的方式,它通过值获取其参数(指向int的指针)。即b将是int *类型的另一个变量,它将是a 副本 。因此b的值也会为NULL。现在在f1中,您可以通过为b分配动态分配的内存地址,将值更改为malloc。可以说内存地址是0x123。由于此分配,b已将其值从NULL更改为0x123,但a(在main中)继续保留NULL ,因为改变b不会改变a,因为它们是两个独立的变量。因此,当您从函数f1返回时,a将保持不变。

有两种方法可以解决这个问题。您可以使函数f1返回已更改的b的值,然后将其分配回main中的两个,您可以传递a by地址以便进行任何更改在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;
}

答案 4 :(得分: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无法存储到指针中。

答案 5 :(得分:0)

函数返回时删除地址int *b。要保存它,您需要使用指针指针

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