首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >作为函数的指针返回和使用malloc

作为函数的指针返回和使用malloc
EN

Stack Overflow用户
提问于 2017-09-17 17:35:16
回答 5查看 2.4K关注 0票数 3

我使用指针作为函数返回,..below是一段简单的代码

主要功能:

代码语言:javascript
复制
void main()
{
    int a = 10, b = 20;
    int *ptr;
    ptr = add(&a, &b);
    printf("sum of a and b is %d\n", *ptr);
}

添加函数:

代码语言:javascript
复制
int* add(int *a, int *b)
{
    int c;
    c = *(a)+*(b);
    return &c;
}

这是正确的工作,给我输出30..

但是,如果在添加之前再添加一个函数printhelloworld();,如下所示

代码语言:javascript
复制
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,并且由于堆栈帧获得freed..so,所以没有定义,我必须使用malloc()修改程序如下所示

代码语言:javascript
复制
int* add(int *a, int *b)
{    
    int* c = (int*)malloc(sizeof(int));
    *c = *(a)+*(b);
    return c;
}

这个很管用。

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

代码语言:javascript
复制
free(c);

如果我在main中使用free(),则c不在作用域内,如果在add中使用'free`‘,则会再次得到未定义的结果。

问:

在我的例子中使用free()的正确方法是什么?

代码语言:javascript
复制
free(C);

repro的全程序

代码语言:javascript
复制
#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);

}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-09-17 18:03:53

加上( int * a,int *b) { int c;c= *(a)+*(b);返回&c;} 这是正确的工作,给我输出30..

这是行不通的,只是在一个简单的情况下:c是一个局部变量,因此存储加法结果的内存在函数返回时释放。变量使用的内存不会立即删除或重用,因此,当您试图在add返回后访问它时,您将得到您预期的值。但是,当您调用另一个函数printhelloworld时,它使用相同的内存作为自己的局部变量,并且在某个时候内存的内容会被更新。

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

如果您想在函数中分配一些内存并返回指向它的指针,那么在函数中调用malloc是正确的。malloc分配的内存在调用free之前仍然有效。由于您需要在使用完内存后调用free,所以这必须在add返回之后发生:您确实需要在main中调用free。能够从不同的函数调用mallocfree是动态内存分配的关键。

您需要传递给free的是malloc返回的指针值。您已经将这个值分配给c,然后从add返回c,所以您需要传递给free的地址是add返回的值。main中的变量c包含与free中的变量c相同的值。您可以使用它访问存储在此地址的值,也可以使用它来释放内存块。

代码语言:javascript
复制
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
}
票数 5
EN

Stack Overflow用户

发布于 2017-09-17 17:55:54

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

你可以动态地分配内存,然后进入兔子洞,找出谁必须释放它。

或者,您可以让add的调用方决定应该在哪里分配新对象。您可以接受指向对象的指针,然后add应该在其中写入:

代码语言:javascript
复制
void add(int *a, int *b, int *c)
{    
    *c = *(a)+*(b);
}

现在调用代码可以很容易地决定使用一个自动变量:

代码语言:javascript
复制
int c;
add(&a, &b, &c);

如果不需要的话,也不用担心动态分配。由于add的责任减少,这使得维护IMO代码变得更容易。

票数 5
EN

Stack Overflow用户

发布于 2017-09-17 17:50:57

如果我在main中使用free(),那么c不在作用域内,它将无法工作,如果在添加中使用‘free’,我将再次得到未定义的结果。

局部变量cadd()中的作用域不相关;您仍然可以访问ptr中main中的malloc‘’ed指针。所以您可以在main()中释放它:

代码语言:javascript
复制
free(ptr);

对(malloc/realloc/calloc来说,最重要的是值是由以前的动态分配( free()等)返回的--它不需要通过相同的变量。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46266963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档