我想知道下面这段代码,它非常简单但是:
char* foo()
{
int i;
char buff[100];
snprintf(buff,100,"This is now written in the stack allocated memory!");
return buff;
}
现在,buff被分配在函数的堆栈中,这意味着每个变量都存在 释放,我们所拥有的是内存泄漏。 但是在已经写好的位置究竟发生了什么?
这些行仍然写在内存中,不是吗?
我可以读一段内存吗?我确实有指针指向段的开头,如果是这样,它将是:
char* bar = foo();
char foobar = bar[0];
我可以写到某个位置吗?类似的例子:
char* bar = foo();
bar[1] = 'i';
将会对此问题的澄清表示赞赏!
答案 0 :(得分:4)
这不是内存泄漏。这是一个悬垂的指针。 foo()
返回指向不再分配的内存的指针。尝试使用此指针从内存中写入或读取是未定义的行为。
内存泄漏是指您分配了不再可访问的内存。例如:
void foo()
{
char *buff = malloc(10);
}
已经分配了10个字节,但是这些10个字节无法被释放。
在你的情况下,你有相反的问题。你有一个指向内存的指针,它已经超出范围而自动释放。一旦以这种方式释放了内存,就不再允许您以任何方式尝试访问它。
答案 1 :(得分:1)
从虚拟内存poit来看,只要您以受控方式执行操作,您就可以按需读写,编译器可以帮助您。但是,当函数返回时,您告诉编译器用于左堆栈帧的内存可能用于其他数据。阅读:您可能会得到超出预期的其他数据。写作:您可以覆盖其他数据。
回归后,内存不需要发生任何事情。它可能会保持当前状态,直到下一个函数调用。 尝试使用调试器检查堆栈。然后你就会知道会发生什么。另外,看一下汇编代码。
另见:Can a local variable's memory be accessed outside its scope?
答案 2 :(得分:0)
简单来说,这不是内存泄漏的情况。问题是你正在返回指向局部变量的指针。您不能返回指向自动局部变量的指针。 buff
是一个自动局部变量,在foo
返回后不再存在,因此指向它的指针无效。
在使用-Wall
和Wextra
编译此类代码时,编译器应该给出警告
function returns address of local variable
答案 3 :(得分:0)
魔术称为未定义行为:您正在返回指向本地对象的指针。查看此指针指向的内容会导致未定义的行为。任何事情都可能发生。 This page试图强调为什么未定义的行为是坏的。