为何删除数组空间后数据仍存在?C++动态数组resize疑问
动态数组resize函数的内存问题解析
问题场景
实现动态数组时,调用resize()函数试图修改数组大小:创建临时数组newData复制原数组数据,让Data指向newData后释放newData,但退出函数后仍能输出Data[2]的值,疑惑为何释放内存后还能访问。
完整代码
#include<iostream> using namespace std; int Length = 0; int* Data; void resize(int,int *); int main() { Data = new int[5];//初始数组分配空间 for (int i = 0; i < 5; i++) Data[i] = i; Length = 5;//初始数组有5个数据 int newLength = 10;//为初始数组分配新尺寸 resize(newLength,Data); cout << Data[2];//输出仍为2 } void resize(int newLength,int *Data) { int* newData = new int[newLength];//临时数组 for (int i = 0; i <Length; i++)//将原数组值复制到临时数组 { newData[i] = Data[i]; } Data = newData; delete[] newData;//释放临时数组空间 }
问题原因拆解
1. 指针传参错误:值传递无法修改外部指针
resize函数的参数int* Data是值传递,函数内部的Data是全局Data的副本,属于独立的局部指针变量。函数内执行Data = newData只是修改了这个局部指针的指向,完全不会影响全局的Data指针。退出函数后,全局Data依然指向最初分配的new int[5]内存,输出的Data[2]是原数组的原始值,和你释放的newData内存毫无关系。
2. 内存释放后的访问是未定义行为
就算修改了全局指针让它指向newData,执行delete[] newData后,该内存会被标记为可被系统回收,但此时内存中的数据可能还没被覆盖,所以偶然能读出值。但这种行为是C++标准中的未定义行为,程序可能在任何时候崩溃、输出错误值,完全不可靠。
修正方案
要实现正确的resize逻辑,需要解决两个问题:修改外部指针的指向、释放原数组的旧内存(而非新分配的内存)。
方案1:使用指针引用作为参数
#include<iostream> using namespace std; int Length = 0; int* Data; void resize(int, int*&); int main() { Data = new int[5]; for (int i = 0; i < 5; i++) Data[i] = i; Length = 5; int newLength = 10; resize(newLength, Data); cout << Data[2]; // 正确输出2 delete[] Data; // 最后记得释放内存 } void resize(int newLength, int*& Data) { int* newData = new int[newLength]; for (int i = 0; i < Length; i++) { newData[i] = Data[i]; } delete[] Data; // 释放原数组的旧内存 Data = newData; // 修改外部指针的指向 Length = newLength; // 更新数组长度 }
方案2:让函数返回新指针
#include<iostream> using namespace std; int Length = 0; int* Data; int* resize(int, int*); int main() { Data = new int[5]; for (int i = 0; i < 5; i++) Data[i] = i; Length = 5; int newLength = 10; int* newData = resize(newLength, Data); delete[] Data; // 释放原内存 Data = newData; Length = newLength; cout << Data[2]; // 正确输出2 delete[] Data; } int* resize(int newLength, int* Data) { int* newData = new int[newLength]; for (int i = 0; i < Length; i++) { newData[i] = Data[i]; } return newData; }
内容的提问来源于stack exchange,提问作者香辛料
相关产品推荐
相关产品推荐

