C++新手求助:数组赋值报错及扩容后数据丢失问题
C++数组扩容与对象赋值问题解决
问题代码与报错
原代码:
#include <iostream> #include "Token.h" int main() { Token* ts = new Token[5]; //创建初始数组 ts[0] = new Token(TT_PLUS, "+"); //添加元素 int size = sizeof(ts) / sizeof(Token); //获取当前大小 size_t newSize = size * 2; //扩容为原来的两倍 Token* newArr = new Token[newSize]; //创建新数组 memcpy(newArr, ts, size * sizeof(Token)); //复制数据 size = newSize; //这段扩容代码是找的,不清楚此行作用... delete[] ts; //删除旧数组 ts = newArr; //数组已更新? std::cout << ts[0].type << std::endl; //尝试获取Token 0的type }
报错信息:
Severity Code Description Project File Line Suppression State Error (active) E0349 没有匹配这些操作数的运算符"=" ATestProgrammingLang C:\Users\usr\source\repos\ATestProgrammingLang\ATestProgrammingLang.cpp 10
Severity Code Description Project File Line Suppression State Error C2679 二进制'=': 未找到接受右操作数类型为'Token *'的运算符(或无法进行可接受的转换) ATestProgrammingLang C:\Users\usr\source\repos\ATestProgrammingLang\ATestProgrammingLang.cpp 10
错误分析与修复
1. 对象赋值类型不匹配(第10行错误)
ts[0]是Token对象,而new Token(TT_PLUS, "+")返回的是Token指针,两者类型无法直接赋值。直接去掉new,用临时对象赋值即可:
ts[0] = Token(TT_PLUS, "+");
如果Token类支持拷贝构造,这样就能正确把临时对象的值赋给数组中的元素。
2. 数组大小计算错误
sizeof(ts)得到的是指针的字节大小(64位系统为8,32位为4),不是数组的总字节数,所以sizeof(ts)/sizeof(Token)的结果完全错误。必须手动跟踪数组的元素数量:
// 初始数组元素数量 int currentSize = 5; // 扩容后的大小 size_t newSize = currentSize * 2;
3. 内存拷贝的潜在问题
memcpy是底层内存拷贝,仅适用于POD类型(简单数据类型如int、char等)。如果Token类包含自定义构造/析构函数、动态分配内存的成员(如std::string),用memcpy会导致对象状态异常、数据丢失。改用循环逐个赋值或std::copy:
// 循环赋值 for (int i = 0; i < currentSize; ++i) { newArr[i] = ts[i]; } // 或用std::copy(需包含<algorithm>头文件) std::copy(ts, ts + currentSize, newArr);
4. 修正后的完整代码
#include <iostream> #include <algorithm> // 用于std::copy #include "Token.h" int main() { int currentSize = 5; Token* ts = new Token[currentSize]; // 创建初始数组 ts[0] = Token(TT_PLUS, "+"); // 正确赋值对象 size_t newSize = currentSize * 2; Token* newArr = new Token[newSize]; // 创建扩容后的数组 // 复制旧数组元素到新数组 std::copy(ts, ts + currentSize, newArr); // 更新数组指针与大小 delete[] ts; ts = newArr; currentSize = newSize; std::cout << ts[0].type << std::endl; // 记得最后释放内存 delete[] ts; return 0; }
额外建议
- 新手优先使用标准库容器
std::vector<Token>,它会自动处理扩容、内存管理,避免手动操作指针的错误:
#include <vector> // ... std::vector<Token> tokens; tokens.reserve(5); // 预分配空间 tokens.emplace_back(TT_PLUS, "+"); // 直接构造对象加入容器 tokens.resize(10); // 扩容到10个元素
内容的提问来源于stack exchange,提问作者crispeeweevile
相关产品推荐
相关产品推荐

