指针作为函数返回并使用malloc

时间:2017-09-17 17:35:17

标签: c pointers function-pointers free

我使用Pointers作为函数返回..下面是一段简单的代码

主要功能:

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不在范围内且不起作用,如果我添加“free”,我将再次得到未定义的结果。

ASK:
在我的案例中使用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);

}

5 个答案:

答案 0 :(得分:5)

我假设int可以替代更复杂的类型。

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

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

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

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

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

如果不需要动态分配,请不要担心。由于add的责任减少,因此更容易维护代码IMO。

答案 1 :(得分:5)

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

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

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

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

如果要在函数中分配一些内存并返回指向它的指针,则在函数中调用malloc是正确的。 malloc分配的内存在您呼叫free之前一直有效。由于您需要在使用完内存后调用free,因此必须在add返回后执行此操作:您需要在free中调用main。能够从不同的函数调用mallocfree是动态内存分配的重点。

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

free

答案 2 :(得分:4)

  

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

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

free(ptr);

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

答案 3 :(得分:1)

虽然变量SELECT c.value('(./Id/node())[1]','int') AS Id, c.value('(./Data/node())[1]','nvarchar(max)') AS Data, row_number() over (order by c.value('(./Id/node())[1]','int')) as ItemOrder FROM @xml.nodes('/Trainings/Training') AS A(c) WHERE c.value('(./Data/node())[1]','nvarchar(max)') != 'test12' FOR XML PATH('Training'),ROOT('Trainings'),TYPE 将超出范围,但控制动态分配内存的正确方法是将其地址保存到任何范围内的变量,并在必要时对该变量调用c。 / p>

答案 4 :(得分:0)

void main()

main shpould返回int。请确保使用main的两个定义之一:

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

其他定义不可移植。

return &c;

返回本地变量的地址是未定义。允许实现对该程序执行任何操作,包括使其看起来在每个月的第17天起作用。

  

在我的情况下使用free()的正确方法是什么

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

ptr = add(&a, &b);
...  
free(ptr);