内存分配和释放他们。 我们应该将它们设置为NULL?(Allocating memory and

2019-09-22 14:30发布

gcc (GCC) 4.7.0
c89

你好,

我想知道如果我想在这里正确。 当我使用malloc分配内存。 的malloc会在内存中返回一个指向大小。

所以之前我分配我的记忆中所有的指针将有NULL值。

使用此代码片段:

struct address *db_row = NULL;

db_row = malloc(sizeof(struct address));
db_row->name = malloc(sizeof(char) * 10);
db_row->email = malloc(sizeof(char) *10);

free(db_row->name);
free(db_row->email);
free(db_row);

我在gdb调试器中分配内存之前db_row做到了这一点:

(gdb) p db_row
$20 = (struct address *) 0x0
(gdb) p *db_row
Cannot access memory at address 0x0

这是正确的,因为没有内存地址已经分配。 后我分配内存,得到类似如下的时候我做同样的:

(gdb) p db_row
$25 = (struct address *) 0x602310
(gdb) p *db_row
$26 = {id = 0, set = 0, name = 0x0, email = 0x0}

然而,当我有空闲内存我仍然得到同样的内存地址,岂不是NULL作为分配任何内存之前的第一种情况?

释放内存后:

(gdb) p db_row
$28 = (struct address *) 0x602310
(gdb) p *db_row
$27 = {id = 6300480, set = 0, name = 0x602330 "", email = 0x602350 " #`"}

正如你可以看到它仍指向同一个内存位置,这是正确的?

最后,我添加了这个在最后,看看我能做到双免费:

if(db_row != NULL) {
    free(db_row);
}

if(db_row != NULL) {
    free(db_row);
}

我得到的第二个呼叫堆栈转储释放。 但是,作为一种安全措施应你总是检查,以确保你是不是试图做一个双免费的吗?

它值得设置指针为NULL后释放他们?

db_row = NULL;

非常感谢您的任何建议,

Answer 1:

但是,作为一种安全措施应你总是检查,以确保你是不是要释放一个NULL指针?

调用free()一个NULL指针是安全的,没有什么会发生。 调用free()NULL指针,你可以明确地做到这一点。 NULL荷兰国际集团的指针调用后free()将防止双重释放同一指针变量:

/* Assuming 'db_row' is referring to a valid address
   at this stage the following code will not result
   in a double free.*/
free(db_row);
db_row = NULL;
free(db_row);

如果另一个指针变量指向相同的地址和被传递到free()然后仍然出现一个双重释放。

仅仅因为一个指针并非是─ NULL并不能保证它指向一个有效的地址。 这是程序员的责任,以确保双free()不发生秒。 NULL一个电话后,ING指针变量来free()帮助,但不提供担保的多个指针变量可以在同一地址被人指指点点。


但是,作为一种安全措施应你总是检查,以确保你是不是试图做一个双免费的吗?

有没有办法查询指针变量,以确定是否在它所占用的地址内存已是free() d。 指针变量拥有一个地址,仅此而已。



Answer 2:

这是很好的做法,设置一个指向null释放它,除非你是在变量的范围结束之后; 是的这是正常的free没有做到这一点。

如果指针为null ,呼吁free上是安全的,并且任何访问都将产生一个核心转储,这是很容易超过内存损坏或双调试free ,如果你使用一个释放的指针未设置为可能出现的null



Answer 3:

之后,我有自由内存我仍然得到同样的内存地址,岂不是NULL作为分配任何内存之前的第一种情况?

由于free()只释放分配给你的内存。 它DOS不设置指针NULL

但是,作为一种安全措施应你总是检查,以确保你是不是要释放一个NULL指针?

如果指针传递给free()是一个空指针,则没有动作发生(C99部分7.20.3.2)。

它值得设置指针NULL后释放他们?

是绝对做所以没有可取之处,更多的时候它最终会隐藏自己的问题,这将在某些或其他形式提高他们的丑陋的头。

这是编程的防守和可疑的风格,以避免悬摆指针或双重释放的问题,其中您尝试保护自己免受free()获取调用同一 pointer.In现实往往还是不出现双重释放问题,当你在不同的指示器到相同的存储器,并且这些不同的指针传递给free()

使得指针的做法NULL什么也不做在第二和更常见的错误的情况。 所有这些情况只能通过把一些好的想法和定期审查代码编写程序来避免。



Answer 4:

为了尽量明确这里,我要通过malloc的男人页面引用:

The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.

因此,回顾一下:

  1. 自由需要由内存分配函数返回一个指针(NULL或有效)
  2. 如果是NULL,没有任何反应
  3. 如果它是一个有效的指针它释放内存

您会在这里注意到它没有提到改变了地址ptr指向。 那是你的事。 所以这是非常安全的事:

int *p = malloc(sizeof(int));
*p = 5;
printf("p=%d\n",*p);
free(p);
p = NULL;

现在,您可以拨打free()整天在你的指针p,你就OK。 如果你很在意具有双重错误free()调用,最近的Linux版本的libc(不迟于5.4.23)和GNU libc的(2.X)的存在代替saftely机制称为MALLOC_CHECK_

而是得到一个堆栈崩溃,你会看到一条消息,如: *** glibc detected *** ./a.out: free(): invalid pointer: 0x0804b008 ***

您可以通过以下方式使用它:

  1. export MALLOC_CHECK_=0到关闭的malloc检查和(可能)让你的程序崩溃
  2. export MALLOC_CHECK_=1 ,你会得到上面的警告消息
  3. export MALLOC_CHECK_=2将调用中止(1),并给你的代码的回溯
  4. export MALLOC_CHECK_=3只是选项1 | 2一起


文章来源: Allocating memory and freeing them. Should we set them to NULL?
标签: c malloc free