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)
非常感谢任何建议,
但作为安全措施,您应该始终检查以确保您没有尝试释放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.指针变量只保存一个地址.