C++动态结构体数组扩容触发std::length_error异常咨询
分析你的
std::length_error异常及代码问题 首先得澄清一个关键误解:你遇到的std::length_error异常并不是堆内存耗尽——这个异常通常和标准库容器(比如std::string)的内部数据损坏有关,和系统剩余RAM没有关系。结合你的代码来看,问题出在数组下标越界和逻辑错误上,具体拆解如下:
1. 数组下标越界触发的未定义行为
C++数组的下标是从0开始的,但你的代码多处错误地从i=1开始遍历:
- 你初始化
friendsList = new frnd[2];,这个数组只有friendsList[0]和friendsList[1]两个有效元素。 - 但在复制到
temp时,你的循环是for (int i = 1; i < 3; i++),当i=2时,你访问了friendsList[2]——这完全超出了数组的合法范围,属于未定义行为。这种越界访问会破坏内存中的数据,比如直接损坏了std::string的内部结构,最终触发std::length_error异常。
2. 无效的复制逻辑导致数据丢失
你的代码里size变量初始值是1,后面复制temp到新的friendsList时,循环条件是for (int i = 1; i < size; i++)——因为size=1,i<1的条件永远不成立,这个循环根本不会执行,导致你之前赋值的"larry"根本没被复制到新的friendsList里。
修正后的代码示例
这里是调整后的正确代码,修复了下标问题和冗余的内存分配:
#include <iostream> #include <string> using namespace std; struct frnd { string firstName; string lastName; int lastTalked; }; int main() { int currentSize = 2; // 初始数组大小为2,对应下标0和1 frnd* friendsList = new frnd[currentSize]; // 给下标1的元素赋值 friendsList[1].firstName = "larry"; // 扩容到4个元素 int newSize = 4; frnd* temp = new frnd[newSize]; // 从0开始遍历所有有效元素 for (int i = 0; i < currentSize; i++) { temp[i] = friendsList[i]; } // 释放旧数组,直接将指针指向新数组(无需再次new) delete[] friendsList; friendsList = temp; currentSize = newSize; // 正常访问friendsList[1] cout << "\n\n" << friendsList[1].firstName << "\n\n"; // 记得最后释放动态内存 delete[] friendsList; system("PAUSE"); return 0; }
额外建议:用标准库容器简化操作
手动管理动态数组很容易出错,C++标准库的std::vector<frnd>可以自动处理扩容、内存释放等操作,代码会更安全简洁:
#include <iostream> #include <string> #include <vector> using namespace std; struct frnd { string firstName; string lastName; int lastTalked; }; int main() { vector<frnd> friendsList(2); // 初始大小为2的动态数组 friendsList[1].firstName = "larry"; friendsList.resize(4); // 自动扩容到4个元素,原有数据会保留 cout << "\n\n" << friendsList[1].firstName << "\n\n"; system("PAUSE"); return 0; }
内容的提问来源于stack exchange,提问作者William FitzPatrick
相关产品推荐
相关产品推荐

