指针作为函数 returns 和 malloc 的使用

Pointers as function returns and use of malloc

我正在使用指针作为函数 returns ..下面是一段简单的代码

主要功能:

void main()
{
    int a = 10, b = 20;
    int *ptr;
    ptr = add(&a, &b);
    printf("sum of a and b is %d\n", *ptr);
}

添加功能:

int* add(int *a, int *b)
{
    int c;
    c = *(a)+*(b);
    return &c;
}

这可以正常工作并给出输出 30..

但是如果你再添加一个函数printhelloworld();然后像下面那样添加

void main()
{
    int a = 10, b = 20;
    int *ptr;
    ptr = add(&a, &b);

    printhelloworld();--this just prints hello world

    printf("sum of a and b is %d\n", *ptr);
}

输出将不再是 30,并且由于堆栈帧被释放而未定义。所以我必须使用 malloc()

修改我的程序,如下所示
int* add(int *a, int *b)
{    
    int* c = (int*)malloc(sizeof(int));
    *c = *(a)+*(b);
    return c;
}

这有效。

但是如果我不释放在堆中分配的内存,它不会永远保留吗?我不应该像下面那样使用 free() 吗?

free(c);

如果我在 main 中使用 free()c 不在范围内并且它不会工作,如果我在 add 中使用 'free`,我将再次得到未定义的结果。

提问:
在我的案例中 free() 的正确使用方法是什么

free(C);

重现程序总数

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

void printhelloworld()
{

    printf("hello world\n");
}

int* add(int *a, int *b)
{

    int* c = (int*)malloc(sizeof(int));

    *c = *(a)+*(b);
    //free(c);
    return c;
}


int main()
{

    int a = 10, b = 20;

    int *ptr;
    ptr =(int*) malloc(sizeof(int));
    ptr = add(&a, &b);

printhelloworld();
printf("sum of a and b is %d\n", *ptr);

}

If I use free() in main,c is not in scope and it won't work, if I use 'free` in add, again I will get undefined result.

add() 中的局部变量 c 的范围不相关;您仍然可以访问 ptr 中 main 中的 malloc'ed 指针。所以你可以在 main() 中释放它:

free(ptr);

free() 重要的是该值是由先前的动态分配(malloc/realloc/calloc 等)返回的 - 它不会必须通过相同的变量。

我假设 int 是更复杂类型的替代品。

可以 动态分配内存,并深入了解谁必须释放它。

或者,您可以让 add 的调用者决定新对象的分配位置。您可以接受指向对象的指针,然后 add 应该写入:

void add(int *a, int *b, int *c)
{    
    *c = *(a)+*(b);
}

现在调用代码可以轻松决定使用自动变量:

int c;
add(&a, &b, &c);

如果不需要,不用担心动态分配。由于 add.

的责任减少,它使得维护代码 IMO 变得更容易
void main()

main 应该 return 一个 int。请确保您使用 main 的两个定义之一:

int main(void)
int main(int argc, char** argv)

其他定义不可移植。

return &c;

返回局部变量的地址是未定义。一个实现可以对这个程序做任何事情,包括让它看起来在每个月的第 17 天工作。

What is the correct way to use free() in my case

正确的做法是在不需要时不要使用指针,但如果您确实使用了指针,则在 main 函数中释放它,如下所示:

ptr = add(&a, &b);
...  
free(ptr);
int* add(int *a, int *b)
{
    int c;
    c = *(a)+*(b);
    return &c;
}

This works correctly and gives me output 30..

这行不通,它只是在一个简单的情况下出现:c是一个局部变量,所以存储加法结果的内存在函数[=44=时被释放]s。变量使用的内存不会立即擦除或重新使用,因此当您尝试在 add return 秒后访问它时,您会得到预期的值。但是,当您调用另一个函数时 printhelloworld,它会为自己的局部变量使用相同的内存,并且在某些时候内存的内容会得到更新。

请注意,即使在简单的情况下,也不能保证您会看到结果。指针使用强化工具或编译器优化可能会导致程序崩溃、显示不同的值或在此时以令人困惑的方式运行。 C 称之为“未定义行为”。

如果你想在一个函数中分配一些内存和return一个指向它的指针,那么在函数中调用malloc是正确的。由 malloc 分配的内存在您调用 free 之前一直有效。由于您需要在使用完内存后调用 free,因此这必须在 add return 之后发生:您确实需要在 [=21] 中调用 free =].能够从不同的函数调用 mallocfree 是动态内存分配的重点。

需要传递给free的是mallocreturn的指针值。您已将此值分配给 c,然后您从 add return c,因此您需要传递给 free 的地址是值 return由 add 编辑。 main 中的变量 ptr 包含与 free 中的变量 c 相同的值。你可以用它来访问存储在这个地址的值,你也可以用它来释放内存块。

int* add(int *a, int *b)
{    
    int* c = malloc(sizeof(int));  // no need for a cast here
    printf("The pointer is %p\n", (void*)c);
    if (c == NULL) { // Abort the program if the allocation failed
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    *c = *(a)+*(b);
    return c;
}

int main()
{
    int a = 10, b = 20;
    int *ptr;
    ptr = add(&a, &b);
    printf("The pointer is still %p\n", (void*)ptr);
    // ...
    printf("sum of a and b is %d\n", *ptr);
    free(ptr); // After this line, you aren't allowed to use the value of ptr any more
    ptr = NULL; // This is not necessary, but it's good practice to ensure that you won't accidentally use the value
}

虽然您的变量 c 将 运行 超出范围,但控制动态分配内存的正确方法是将其地址保存到任何范围内的变量并调用 free()必要时该变量。