C++运行时数组重分配异常:垃圾值与程序延迟问题排查
C++动态扩容数组类的问题修复
问题说明
我用C++实现了一个动态扩容的数组类,初始长度设为8,空间不足时自动扩容为原长度的两倍。但运行时遇到两个问题:
- 本该正常存储的元素会显示垃圾值
- 程序执行完最后一条输出语句后不会立即终止,会卡顿几秒
原代码
#include <iostream> using namespace std; class Array { private: int length = 8; int occupied_length = 0; int* array = new int[length]; void reallocate_array() { array = (int*) realloc(array, length*2); length = length * 2; } public: Array() { cout << "How many elements do you want in the array: "; cin >> occupied_length; if (occupied_length > length) // In case array is full, it needs to be reallocated reallocate_array(); for (int i = 0; i < occupied_length; i++) cin >> *(array + i); Print(); } ~Array() { delete array; } void insert(int pos, int data) { if (pos > occupied_length) {cout << "Invalid Position!\n"; return; } occupied_length += 1; if (occupied_length > length) { reallocate_array(); } if (pos == occupied_length){ *(array+occupied_length) = data; return;} for(int i = occupied_length-2; i >= pos-1; i--) *(array+i+1) = *(array+i); *(array + pos - 1) = data; } int size() { return occupied_length; } void Print() { for(int i =0; i <occupied_length; i++) { cout << *(array+i) << " "; } cout << endl; } }; int main() { Array arr; arr.insert(7,45); arr.Print(); arr.insert(3,35); arr.Print(); arr.insert(4,86); arr.Print(); cout << arr.size() << endl; return 0; }
问题分析
- 混合使用C/C++内存管理函数:C++中用
new[]分配的内存,不能用C标准库的realloc重新分配,两者内存管理机制不兼容,会导致内存数据错乱,出现垃圾值。 - 数组越界访问:
insert函数中,当pos == occupied_length(此时occupied_length已经+1),赋值给*(array+occupied_length),但数组的有效索引范围是0 ~ occupied_length-1,这里越界写入会破坏内存结构。 - 析构函数错误:用
delete释放new[]分配的内存(或者realloc处理过的内存),属于未定义行为,会导致程序退出时卡顿甚至崩溃。 - 构造函数扩容逻辑不全:如果用户输入的元素数量远大于初始长度(比如100),只扩容一次到16还是不够,无法满足需求。
修复后的代码
#include <iostream> #include <algorithm> // 用std::copy复制元素 using namespace std; class Array { private: int length = 8; int occupied_length = 0; int* array = new int[length]; void reallocate_array() { // 用C++方式扩容:分配新内存,复制旧元素,释放旧内存 int new_length = length * 2; int* new_array = new int[new_length]; // 复制已有的元素 copy(array, array + occupied_length, new_array); // 释放旧内存 delete[] array; array = new_array; length = new_length; } public: Array() { cout << "How many elements do you want in the array: "; cin >> occupied_length; // 循环扩容直到长度足够 while (occupied_length > length) { reallocate_array(); } for (int i = 0; i < occupied_length; i++) { cin >> array[i]; // 用下标更直观 } Print(); } // 析构函数用delete[]释放数组 ~Array() { delete[] array; } void insert(int pos, int data) { // pos的合法范围是1~occupied_length+1(支持插入到末尾) if (pos < 1 || pos > occupied_length + 1) { cout << "Invalid Position!\n"; return; } occupied_length += 1; // 空间不足则扩容 while (occupied_length > length) { reallocate_array(); } // 插入到末尾的情况 if (pos == occupied_length) { array[occupied_length - 1] = data; return; } // 从后往前移动元素,腾出位置 for(int i = occupied_length - 2; i >= pos - 1; i--) { array[i + 1] = array[i]; } array[pos - 1] = data; } int size() { return occupied_length; } void Print() { for(int i = 0; i < occupied_length; i++) { cout << array[i] << " "; } cout << endl; } }; int main() { Array arr; arr.insert(7,45); arr.Print(); arr.insert(3,35); arr.Print(); arr.insert(4,86); arr.Print(); cout << arr.size() << endl; return 0; }
修复说明
- 替换
realloc为C++原生的new[]和delete[],用std::copy安全复制元素,避免内存管理冲突。 - 修复
insert函数的越界问题,插入到末尾时正确使用array[occupied_length-1]。 - 完善构造函数和
insert中的扩容逻辑,用while循环确保扩容到足够长度。 - 修正析构函数为
delete[] array,匹配new[]的分配方式。 - 调整
insert的参数校验,确保pos的合法范围是1到当前元素数+1(支持插入到末尾)。
内容的提问来源于stack exchange,提问作者Dev_A
相关产品推荐
相关产品推荐

