2017-08-11 73 views
0

示例代码是这样的:任何方式都可以识别内存地址是否可用?

#include <iostream> 

using namespace std; 

int main() 
{ 
    int* addr = (int*)malloc(100); 
    cout << "Hello World" << endl; 
    printf("addr#1=%p\n",addr); 
    free(addr); 
    printf("addr#2=%p\n",addr); 

    return 0; 
} 

我知道addr#1addr#2将打印相同的地址。 但是有没有一种方法可以识别可以自由使用的地址?

有人说这是不可能的,除非你重新分配NULLnullptraddr来识别。好的,如果指针指向一个对象,并且该对象被删除,结果是一样的?

+1

可能的重复[如何检查指针是否已在C中释放?](https://stackoverflow.com/questions/8300853/how-to-check-if-a-pointer-is-freed-already -in-c) –

+0

好吧,如果指针指向一个对象,并且该对象被删除,结果是一样的? – naive231

+0

如果这是C(标记为),'printf(“addr#2 =%p \ n”,addr);'调用*未定义行为*试图在'free(addr)'后面访问'addr'。 –

回答

0

你可以自由包装并始终注意初始化指针。

void myfree(void **ptr) 
{ 
    free(*ptr); 
    *ptr = NULL; 
} 

所以每个空闲都会赋值NULL。如果指针为NULL,则可以检入程序。这只是某种解决方法

+1

多次引用同一个内存位置如何? –

0

我知道addr#1和addr#2会打印相同的地址。但任何 的方式可以确定一个可以自由使用的地址吗?

理想的方式,以确定是否由malloc分配一块存储器是将指针指向设定为一块的存储器是NULL,包括所有其它指针,其可以潜在地指向原始块的存储器。

好的,如果指针指向一个对象,并且该对象被删除,结果是一样的?

只是因为一块内存被释放并不意味着原来在那个内存位置会被瞬间擦除。你可以调用它,看看你原来的东西,一些随机的东西,或者你的程序可能会崩溃;这是未定义的行为。 当你说“删除”时,我假设你意味着释放先前分配的一块内存。

有人说,除非你重新分配NULL或nullptr到地址来标识

有由kennytm一个有趣的答案通过的mcheck使用和mprobe这里How to check if a pointer is freed already in C? 发现这是不可能的,其中这些功能钩到malloc和对堆进行瓶坯常量检查。你可以制作一系列检查来确定一个变量是否已被释放,但这些函数纯粹用于调试,而传递分配的内存则是安全的方式。

0

我知道addr#1和addr#2会打印相同的地址。但是有什么方法可以确定一个可以自由使用的地址?

不容易或便携。这是特定于C运行时库的行为,因此完全取决于实现细节。此外,这是未定义的行为(免费使用)。

例如,您需要使用堆检查例程,如使用GCC的mprobe来查询运行时的状态。

有人说这是不可能的,除非你将NULL或nullptr重新分配给addr来标识它。

不,只会改变你的有关该特定内存使用或状态的观点。它根据实际拥有并管理此信息的运行时库说明系统的状态。

好的,如果指针指向一个对象,并且该对象被删除,结果是一样的?

是的,无论是指向对象的指针还是指向POD的指针(结果如您所示),结果都是一样的。

传统观点认为,如果您遵循一定的规则和最佳实践来处理内存管理问题,那么您绝对不应该担心这类问题。

这整个问题是使用smart pointers的一个很好的激励示例!然后整个问题就消失了。

相关问题