c/c++语言开发共享什么时候在C中释放指针以及如何知道它是否被释放

我是C的新手,试图找出C中的内存分配,我有点困惑

#include  #include  typedef struct { int a; } struct1_t; int main() { funct1(); //init pointer return 1; } int funct2(struct1_t *ptr2struct) { printf("print a is %dn",ptr2struct->a); //free(ptr2struct); printf("value of ptr in funct2 is %pn", ptr2struct); return 1; //success } int funct1(){ struct1_t *ptr2struct = NULL; ptr2struct = malloc(sizeof(*ptr2struct)); ptr2struct->a = 5; printf("value of ptr before used is %p", ptr2struct); if (funct2(ptr2struct) == 0) { goto error; } free(ptr2struct); printf("value of ptr in funct1 after freed is is %pn", ptr2struct); return 1; error: if(ptr2struct) free(ptr2struct); return 0; } 

我有function1调用function2,并在使用funct1中分配的指针后,我尝试释放指针。 我创建了一个案例,如果funct2中的返回值不是1,则再次尝试释放指针。

我的问题如下

哪个练习更好,如果我应该释放funct2中的内存(在我传递之后)或者在funct1中(在我完成获取funct1的返回值之后)第二个问题是这是否正确产生goto错误,并且错误:

 if(ptr2struct) free(ptr2struct); 

我的第三个问题是,如何检查已分配的值是否已被释放? 因为在获得返回值之后,我释放指针,但是如果我打印它,它显示与分配的一个相同的位置(所以不是空指针)。

    1)我应该在调用函数或被调用函数中释放它吗?

    我尝试在与malloc-ing相同的function中进行自由处理。 这样可以将内存管理问题保存在一个地方,并且可以更好地分离关注点,因为在这种情况下,被调用的函数也可以使用未被malloc编辑的指针或两次使用相同的指针(如果你想这样做) )。

    2)做“转到错误”是否正确?

    是! 通过跳转到函数末尾的单个位置,您可以避免复制资源释放代码。 这是一种常见的模式,并没有那么糟糕,因为“goto”只是作为一种“返回”语句,并没有做任何它更为人所知的棘手和邪恶的东西。

     //in the middle of the function, whenever you would have a return statement // instead do return_value = something; goto DONE; //... DONE: //resorce management code all in one spot free(stuff); return return_value; 

    另一方面,C ++有一种巧妙的方法来进行这种资源管理。 由于析构函数在函数退出之前被确定性地调用,因此它们可以用来巧妙地打包这个资源管理之王。 他们称这种技术为RAII

    其他语言必须处理的另一种方式是终止块。

    3)我可以看看指针是否已被释放?

    可悲的是,你做不到。 有些人在释放它之后将指针变量值设置为NULL。 它没有受到伤害(因为它的旧值在被释放之后不应该被使用)并且它具有释放空指针的良好属性被指定为无操作。

    但是,这样做并非万无一失。 注意让其他变量别名相同的指针,因为它们仍然包含旧值,现在是一个危险的悬空指针。

    在指针上调用free()不会改变它,只将内存标记为空闲。 您的指针仍将指向包含相同值的相同位置,但该值现在可以随时被覆盖,因此在释放后不应使用指针。 为了确保这一点,最好在释放它之后始终将指针设置为NULL。

    我的问题如下

    哪个练习更好,如果我应该在funct2中释放内存(在我通过之后)或在funct1中(在我获得funct1的返回值之后)

    这是一个“所有权”问题。 谁拥有分配的内存。 通常,这必须根据您的程序设计来决定。 例如,func1()的唯一目的可能是仅分配内存。 也就是说,在你的实现中,func1()是内存分配的函数,然后“调用”函数使用内存。 在这种情况下,释放内存的所有权是使用func1的调用者而不是使用func1()。

    第二件事是,这是否是正确的goto错误和错误:使用“goto”通常是不赞成的。 它会导致代码混乱,可以轻松避免。 但是,我说“一般”。 有些情况下goto可以安静方便且有用。 例如,在大型系统中,系统配置是一大步。 现在,假设您为系统调用一个Config()函数,该函数为函数中不同点的不同数据结构分配内存,如

      config() { ...some config code... if ( a specific feature is enabled) { f1 = allocateMemory(); level = 1; } ....some more code.... if ( another feature is enabled) { f2 = allocateMemory(); level = 2; } ....some more codee.... if ( another feature is enabled) { f3 = allocateMemor(); level =3; } /*some error happens */ goto level_3; level_3: free(f3); level_2: free(f2); level_1: free(f1); } 

    在这种情况下,您可以使用goto并优雅地释放分配的内存,直到配置失败。

    但是,在您的示例中足以说明goto很容易避免,应该避免。

    我的第三个问题是,如何检查已分配的值是否已被释放? 因为在获得返回值之后,我释放指针,但是如果我打印它,它显示与分配的一个相同的位置(所以不是空指针)。

    简单。 将释放的内存设置为NULL。 除MK提到的另一个优点是,将NULL指针传递给free将导致NOP,即不执行任何操作。 这也可以帮助您避免任何双重删除问题。

    我将要分享的是我自己在C中的开发实践。它们绝不是组织自己的唯一方式。 我只是简单介绍一种方式。

    好吧,所以,在许多方面,“C”是一种松散的语言,所以很多纪律和严格来自于自己作为开发者。 我一直在“C”开发专业20多年,我很少需要修复我开发的任何生产级软件。 虽然相当一部分成功可能归功于经验,但其中很大一部分植根于一贯的实践。

    我遵循一系列非常广泛的开发实践,并将所有内容作为命名约定的标签来处理,而不是。 我将自己限制在处理一般结构,特别是内存管理方面。

    foo.h中:

     struct foo; typedef struct foo foo_t; void set_e1(foo_t f, int e1); int get_ei(foo_t f); int set_buf(foo_t f, const char *buf); char * get_buf_byref(foo_t f) char * get_buf_byval(foo_t f, char *dest, size_t *dlen); 

    foo.c的:

     #include  struct foo { int e1; char *buf; ... }; void set_e1(foo_t f, int e1) { f->e1 = e1; } int get_ei(foo_t f) { return f->e1; } void set_buf(foo_t f, const char *buf) { if ( f->buf ) free ( f->buf ); f->buf = strdup(buf); } char *get_buf_byref(foo_t f) { return f->buf; } char *get_buf_byval(foo_t f, char **dest, size_t *dlen) { *dlen = snprintf(*dest, (*dlen) - 1, "%s", f->buf); /* copy at most dlen-1 bytes */ return *dest; } 

    您将看到我上面概述的方法与面向对象编程之间的强烈相似性。 这意味着……

    如果你像这样保持接口干净,那么你是否必须将实例变量设置为NULL并不重要。 希望代码可以使自己适应更严格的结构,而不太可能出现愚蠢的错误。

    希望这可以帮助。

    我知道这已经回答了,但我想提出我的意见。 据我所知,当您使用诸如here(指针)之类的参数调用函数时,参数将被推送到堆栈(FILO)


    因此,传递给函数的指针将自动弹出堆栈,但不会释放funct1()中的指针。 因此,您需要释放funct1中的指针()如果我错了,请纠正我。

    需要了解更多c/c++开发分享什么时候在C中释放指针以及如何知道它是否被释放,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享什么时候在C中释放指针以及如何知道它是否被释放相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/980089.html

      (0)
      上一篇 2021年12月13日
      下一篇 2021年12月13日

      精彩推荐