示例代码如下:
#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#1
和addr#2
会打印相同的地址。
但有没有办法确定可以免费使用的地址?
有人说除非你将NULL
或nullptr
重新分配给addr
以确定这一点,否则无法做到这一点。好的,所以如果指针指向一个对象,并删除该对象,结果是一样的吗?
答案 0 :(得分:0)
你可以自由包装并始终注意初始化指针。
void myfree(void **ptr)
{
free(*ptr);
*ptr = NULL;
}
所以每个free都会赋值NULL。如果指针为NULL,您可以签入程序。它只是某种解决方法
答案 1 :(得分:0)
我知道addr#1和addr#2会打印相同的地址。但是没有 方式可以确定一个可以免费使用的地址吗?
确定malloc
分配的内存是否将指向该内存的指针设置为NULL
的理想方法,包括可能指向原始内存的所有其他指针一块记忆。
好的,那么如果指针指向一个对象,并且该对象被删除,那么结果是一样的吗?
仅仅因为释放了一块内存并不意味着最初在该内存位置的内容将被立即删除。你可以打电话给它,看看你原来的东西,一些随机的东西,或者你的程序可能会崩溃;这是未定义的行为。 当你说“删除”时,我假设你暗示释放以前分配的内存。
有人说除非你将NULL或nullptr重新分配给addr来识别
,否则这是不可能的。
通过mcheck
和mprobe
的使用,kennytm在这里找到了一个有趣的答案,其中这些函数挂钩到malloc
并在堆上执行常量检查。您可以有效地制作一系列检查以确定是否已释放变量,更多信息How to check if a pointer is freed already in C?
,但这些函数纯粹用于调试,NULL
传递分配的内存是安全的方法。
答案 2 :(得分:0)
我知道addr#1和addr#2会打印相同的地址。但是,有任何方法可以确定一个可以免费使用的地址吗?
不容易或便携。这特定于C运行时库的行为,因此完全取决于实现细节。此外,这是未定义的行为(使用后免费)。
例如,您需要使用堆检查例程(例如mprobe
和GCC)在运行时查询状态。
有人说除非你将NULL或nullptr重新分配给addr来识别它,否则它是不可能的。
不,这只会改变您对该特定内存的使用或状态的视角。它没有说明根据实际拥有和管理此信息的运行时库的系统状态。
好的,那么如果指针指向一个对象,并且该对象被删除,那么结果是一样的吗?
是的,无论是指向对象的指针还是指向POD的指针(如示例所示),结果都是相同的。
传统观点认为,如果你遵循某些规则和最佳实践来处理内存管理,你就不应该担心这类问题。
这整个问题是使用smart pointers的一个很好的激励范例!然后整个问题就消失了。