这是不安全的。原因很简单:
函数的任何变量都会分配到函数返回后释放内存的堆栈上。内存被释放的事实并不意味着它的内容被改变了。
这意味着你没有把在变量char buff[20]
存储器内容仍处于buff
或ptr
(因为ptr=buff
)内存位置。无论何时调用另一个函数(或执行另一个块),它的函数/块变量也将进入堆栈,从而创建更改位置ptr
指向的内存内容的可能性。
在您编写的strcpy
示例中,您足够幸运地发现strcpy函数变量没有进入旧的buff
阵列中的位置。这就是您得到安全的印象。
结论是,你无法真正保证在两次函数调用之间堆栈的已释放内存不会改变。
解决方法是使用malloc
,因为malloc
不会在堆栈上分配内存,而是在堆上分配内存。除非您选择这样做(通过免费通话),否则堆内存不会被释放。
这种方法可以保证ptr
指向的内存可以安全地被任何其他函数使用。
这种解决方案的缺点是内在的:曾经的记忆不释放,除非你编程方式做到这一点,如果你忘记释放该内存和失去ptr
的内容,这种记忆会在那里,分配给你的程序,但从来没有只要你的程序运行,就可以实现。该内存将成为内存泄漏:-)
这就是为什么一些语言有垃圾收集一个...但这是另一个故事了:-)
PS:我认为它是安全的(如果你的程序是单线程的),但我不推荐,做这样的事情:
{
char safe_buffer[20];
char *unsafe_ptr;
int i;
unsafe_ptr = f1();
/*Copy the buffer without calling any function
not to change the stack content
*/
for(i=0;i<20 && *(unsafe_ptr + i) != 0;i++)
{
*(safe_buffer + i) = *(unsafe_ptr + i);
}
*(safe_buffer + i) = 0;
f2(safe_buffer);
}
来源
2010-02-26 13:04:20
Edu
+1非常多。 – Tom 2010-02-26 12:46:46
它正常工作的原因是在x86上,buff数组从低位地址填充到高位地址,并且可能不会被strcpy的堆栈使用所触及。不要这样做:由于信号和中断等异步事件,堆栈使用可能会有所不同。 – 2010-02-26 12:57:25