首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C在释放内存时将双精度类型的变量转换为char类型的变量

C在释放内存时将双精度类型的变量转换为char类型的变量
EN

Stack Overflow用户
提问于 2013-06-12 01:36:16
回答 3查看 191关注 0票数 3

在处理一个库时,我在提供的示例源代码中发现了以下代码:

代码语言:javascript
复制
x     = (double *) malloc (narcs  * sizeof (double));
dj    = (double *) malloc (narcs  * sizeof (double));
pi    = (double *) malloc (nnodes * sizeof (double));
slack = (double *) malloc (nnodes * sizeof (double));

我在这里没有发现什么特别的东西,但是在释放内存时,源代码示例执行以下操作:

代码语言:javascript
复制
free_and_null ((char **) &x);
free_and_null ((char **) &dj);
free_and_null ((char **) &pi);
free_and_null ((char **) &slack);

free_and_null代码为:

代码语言:javascript
复制
static void
free_and_null (char **ptr)
{
    if ( *ptr != NULL ) {
    free (*ptr);
    *ptr = NULL;
    };
};

我的问题不是为什么,当释放之前分配的内存时,它会转换为char双指针。我的问题是,为什么这样做,使用自定义函数来释放内存,以及为什么选择char **作为该函数的参数。

我知道这个问题肯定会发生,因为我对C语言的了解仍然有限,但无论如何,有人能解释为什么要这样做吗?这是不是一个好的实践。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-12 01:39:34

我不得不同意你的观点--这段代码有点奇怪。作者没有理由不能简单地使用void **

此外,由于free(NULL)是完全合法的,因此if (*ptr != NULL)检查是不必要的。大括号后面的;字符也不是必需的。

更简单的版本可能如下所示:

代码语言:javascript
复制
static void free_and_null(void **ptr)
{
    free(*ptr);
    *ptr = NULL;
}

这个函数存在的原因是为了确保释放的指针被设置为NULL,这有助于检测释放后使用的bug,并完全避免双重释放的bug。

编辑:正如下面StarPilot所建议的,检查ptr本身是否为空可能是个好主意:

代码语言:javascript
复制
static void free_and_null(void **ptr)
{
    if (ptr)
    {
        free(*ptr);
        *ptr = NULL;
    }
}
票数 9
EN

Stack Overflow用户

发布于 2013-06-12 01:40:00

额外的间接层(**)的原因是因为这允许free_and_null的作者将指针设置为NULL。如果它们只是简单地传递*或x,那么它们将拥有通过值传递的指针的副本。

代码语言:javascript
复制
static void
free_and_null (char *ptr)
{
    if ( ptr != NULL ) {
    free (ptr);
//    *ptr = NULL; CAN'T DO THIS NOW
    };
};

在分配的内存被释放后将指针重置为NULL不是一个坏主意,因为它可以帮助检测内存泄漏。我不会完全遵循上面作者的风格,但我认为这可以帮助你理解其中的原理。正如卡尔指出的那样,void **可能是一个更合适的签名。您经常会在C代码中看到人们使用char*作为一种“通用”的指针类型-这是错误的,在这种情况下没有充分的理由使用char。

票数 2
EN

Stack Overflow用户

发布于 2013-06-13 18:40:38

另一种方法是避免指针指向指针,简单地说就是:

代码语言:javascript
复制
void *free_and_null_back(void *p) {
    free(p);
    return NULL;
    }

用法:

代码语言:javascript
复制
p = free_and_null(p);

或者,对于#define粉丝们:

代码语言:javascript
复制
#define free(p) free(p);(p)=null;

显然,这伴随着所有关于#define危险的常见警告...

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

https://stackoverflow.com/questions/17050286

复制
相关文章

相似问题

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