为什么返回后仍然可以访问函数中静态分配的数组?

问题描述 投票:0回答:2

我尝试运行这个简单的代码并期待它会崩溃:

#include <stdio.h>

void setPtrOnTempData(char** ptr) {
  char str[] = "AAAA";
  *ptr = str;
}

int main() {
  char temp[] = "Paras";
  temp[3] = 'F';

  char* ptr = temp;
  ptr++;
  ptr[3] = 'F';
  printf("%s", ptr);  // prints "arFF"

  setPtrOnTempData(&ptr);

  ptr[0] = 'F';
  printf("%s", ptr);  // prints "FAAA"

  return 0;
}

如果我没记错的话,我这么想的原因是:

  1. 静态分配数组的元素都分配在堆栈中,因此函数返回后我失去了对它的控制。
  2. 数组变量是该数组在堆栈中的基元素的地址,因此作为参数传递的指针的赋值将指向堆栈中丢失的位置。

但结果是我仍然可以访问一些内存,其中分配了数组,并且我仍然能够更改该数组的数据。

为什么会这样,我的观点错在哪里?谢谢!!

arrays c pointers memory stack
2个回答
0
投票

不是 C 开发人员。但我认为问题出在您的代码中,“setPtrOnTempData”函数将本地数组的地址分配给主函数中的指针。但是当函数返回时,本地数组 str[] 被释放。

您正在 setPtrOnTempData 函数中创建一个本地数组 str[]。但这个数组的作用域仅在函数内。因此,当您分配 *ptr = str 时,您将本地数组 str 的地址分配给 ptr,该地址指向 main 中的 ptr。但是当它返回时被释放时 它可能看起来有效,但它访问无效内存,导致这种奇怪的情况。


0
投票

当您访问生命周期已结束的变量的内存时(正如您在此处所做的那样),它会导致代码中出现未定义的行为

如果行为未定义,则无法保证您的代码会做什么。它可能会崩溃,可能会表现出奇怪的行为,或者(如您的情况)它可能看起来工作正常。

© www.soinside.com 2019 - 2024. All rights reserved.