You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:55:24