从函数返回时的写入内存

Written memory when returning from function

本文关键字:内存 函数 返回      更新时间:2023-10-16

我想知道以下一段代码,它非常简单,但还没有:

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';
    
  • 一般来说,为什么它被认为是内存泄漏? 我们不能再次重新分配这个位置吗?

将不胜感激有关此问题的澄清!

这不是内存泄漏。 这是一个悬而未决的指针。 foo()返回指向不再分配的内存的指针。 尝试使用此指针从内存中写入或读取是未定义的行为。

内存

泄漏是指分配了不再可访问的内存。 例如:

void foo()
{
   char *buff = malloc(10);
}
已分配 10 个字节

,但无法释放这 10 个字节。

在您的情况下,您有相反的问题。您有一个指向内存的指针,该内存已因超出范围而自动释放。 以这种方式释放内存后,您将不再被允许尝试以任何方式访问它。

从虚拟内存位置来看,只要您以受控的方式读取和写入堆栈,编译器就会为您提供帮助。但是,当函数返回时,您告诉编译器用于左堆栈帧的内存可能用于其他数据。阅读:您可能会获得超出预期的数据。写入:您可以覆盖其他数据。

返回时,内存不需要发生任何事情。它可能保持其当前状态,直到下一次函数调用。尝试使用调试器检查堆栈。然后你会知道会发生什么。另外,请查看汇编代码。

另请参阅:是否可以在其范围之外访问局部变量的内存?

这种魔术被称为未定义行为:你返回一个指向本地对象的指针。查看此指针指向的内容会导致未定义的行为。任何事情都可能发生。本页试图强调为什么未定义的行为是不好的。

简单来说,内存泄漏不是这种情况。问题是您正在返回指向局部变量的指针。不能返回指向自动局部变量的指针。 buff是一个自动局部变量,在foo返回后它不再存在,因此指向它的指针无效。
在使用-WallWextra编译此类代码时,编译器应向您发出警告

function returns address of local variable