分配内存并释放它们.我们应该将它们设置为NULL吗?

ant*_*009 3 c malloc free

gcc (GCC) 4.7.0
c89
Run Code Online (Sandbox Code Playgroud)

你好,

我想知道我在这里是否正确思考.当我使用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);
Run Code Online (Sandbox Code Playgroud)

我在分配内存之前在db_row的gdb调试器中完成了这个:

(gdb) p db_row
$20 = (struct address *) 0x0
(gdb) p *db_row
Cannot access memory at address 0x0
Run Code Online (Sandbox Code Playgroud)

哪个是正确的,因为没有分配内存地址.我分配内存后,当我这样做时,我得到以下内容:

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

但是,在释放内存之后,我仍然得到相同的内存地址,如果在分配任何内存之前第一种情况下它不是NULL吗?

释放内存后:

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

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

最后,我在最后添加了这个,看看我是否可以实现双倍免费:

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

if(db_row != NULL) {
    free(db_row);
}
Run Code Online (Sandbox Code Playgroud)

我在第二次免费通话时得到一个堆栈转储.但作为安全措施,你应该经常检查以确保你没有尝试双重免费吗?

释放后它值得将指针设置为NULL吗?

db_row = NULL;
Run Code Online (Sandbox Code Playgroud)

非常感谢任何建议,

hmj*_*mjd 5

但作为安全措施,您应该始终检查以确保您没有尝试释放NULL指针吗?

free()使用NULL指针调用是安全的,不会发生任何事情.调用free()不是NULL指针,你可以明确地这样做.NULL在调用之后执行指针free()会阻止同一指针变量上的double 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);
Run Code Online (Sandbox Code Playgroud)

如果另一个指针变量指向同一个地址并传递给free()那么仍然会发生双重释放.

仅仅因为指针不是 - NULL不保证它指向有效地址.程序员有责任确保free()不会出现双重问题.NULL在调用help之后调用指针变量free()但不提供保证,因为多个指针变量可以指向同一个地址.


但作为安全措施,你应该经常检查以确保你没有尝试双重免费吗?

无法查询指针变量以确定它所保存的地址处的内存是否已经为free()d.指针变量只保存一个地址.