有没有办法知道指针是指向动态分配的内存还是静态分配的内存?
数组作为指向函数的指针传递
void func (int* p)
{
if( p )
{
cout << p[0] << p[1] ;
...
// func has a responsibility to deallocate what p is pointing
}
}
int main()
{
int a[] = {10, 20, 30, 50};
func(a);
...
return 0;
}
如果解除分配的所有权转移到func。 func p如何知道'p'是指向动态分配的内存还是静态分配的内存?
答案 0 :(得分:4)
你不能知道这一点。这是您的功能定义。更喜欢使用智能指针,或者你必须在函数文档中明确说明它接管传递的对象或数组的所有权。
答案 1 :(得分:2)
没有可移植的方法来确定指针是指向动态分配的内存还是指向静态分配的内存。通过仔细检查指针是否指向您在程序中加载的任何二进制和共享库的数据段或bss段之一,可以扣除此信息。即便如此,静态和动态分配的内存之间的界限也很模糊:您认为以后是动态还是静态加载共享库的内存?
答案 2 :(得分:1)
首先,调用者有责任使用具有合适参数的函数,并且编码器明确表示此函数会尝试释放作为参数传递的指针。
其次,有一些算法功能管理内存不是一个好习惯。主要原因是您可能希望在输入的子集上使用它。例如,如果计算数组的总和,您可能希望能够计算从索引3开始的子数组的总和。
调用者的工作是管理内存,而不是你的内存。只是不要在执行其他操作的函数中放置任何释放。
无论如何,您可以检测地址是否在堆栈中,请参阅1 但是请注意,不在堆栈上并不意味着它在堆上分配,它可能指向一些静态数据,如字符串文字。
答案 3 :(得分:0)
你无法说出来。
你应该在&#34;相同类型的地方释放记忆&#34;你分配它。从广义上讲,这意味着如果函数的调用者分配内存,那么调用者应该释放它。同样,如果你提供一个分配内存的函数,那么提供另一个来释放它。
有些人喜欢在一个函数中分配内存,并让调用者有责任释放它。但是这可能会导致问题,特别是如果函数是单独编译给调用者的话;例如在dll或共享对象中。
您提出的建议:删除在呼叫者中分配的功能中的内存是最糟糕的。 不要这样做。
答案 4 :(得分:0)
不仅你不能真正了解它,你甚至无法告诉指针是否有效。
int* x = 0xDEADBEEF;
但并非所有人都失去了。你可以做各种各样的技巧,至少部分地实现这个目标。 其中一些包括:
new
和delete
。除非您的某些类超载new
和delete
运算符,否则您可以捕获大部分动态分配。如果您使用的是malloc
,则无法使用此功能。HeapAlloc
,从而跟踪一些内存地址。