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

自定义C++模板Array类malloc报错排查:小容量数组触发异常

自定义模板Array类的内存问题解析

问题代码

Array类实现

template<typename T>
class Array{
public:
    Array(size_t size) : array_size(size){
        this->m_Data  = (T*)malloc(sizeof(T) * size);
    }
    
    void insert(size_t index, T value){
        size_t temp_size = this->array_size + 1;
        T *temp = (T*)malloc(sizeof(T) * temp_size );
        //memcpy(temp, this->m_Data, this->array_size );
        for(size_t l = 0; l < temp_size; l++ )
            temp[l] = this->m_Data[l];

        for(size_t i = temp_size; i >= index; i--){
            temp[i] = temp[(i-1)];
        }
        temp[index - 1] = value;
        
        free(this->m_Data);
        this->m_Data = NULL;
        this->m_Data = temp;
        this->array_size = temp_size;
        //free(temp);
        //delete(temp);
    }
    
    void append(T value){
        size_t temp_size = this->array_size + 1;
        std::cout << "temp_size: " << temp_size << std::endl;
        std::cout << "sizeof(T): " << sizeof(T) << std::endl; // returns 4
        std::cout << "temp_size * sizeof(T): " << (temp_size * sizeof(T)) << std::endl; // returns 44
        T *temp = (T*)malloc((temp_size * sizeof(T)));     // error!
    }
    
    
private:
    size_t array_size;
    T *m_Data;
};

测试代码

int main(int argc, char *argv[])
{
    Array<int> data(9); 
    data.insert(1, 100);  // seams to work fine
    data.append(100000);
}

问题原因分析

1. insert函数中调用free(temp)导致乱码的原因

temp是你新分配的内存块,最后你把this->m_Data指向了temp,这块内存已经成为Array类的有效数据存储区。如果调用free(temp),会直接释放这块内存,此时m_Data变成野指针,后续访问数组元素时读取的是已释放的无效内存,自然会出现乱码。这里绝对不能free temp,因为它已经是数组的新数据容器。

2. append函数malloc出错的根源:insert中的内存越界破坏了堆

append的malloc写法本身没问题,但insert函数里的两处内存越界操作已经破坏了堆内存结构,导致后续malloc调用失败:

  • 第一个循环越界:
    for(size_t l = 0; l < temp_size; l++ )
        temp[l] = this->m_Data[l];
    
    temp_size是原数组大小+1,而this->m_Data只有array_size个元素,当l >= array_size时,m_Data[l]属于越界访问,会读写不属于数组的内存区域,破坏堆的元数据。
  • 第二个循环越界+无符号类型溢出:
    for(size_t i = temp_size; i >= index; i--){
        temp[i] = temp[(i-1)];
    }
    
    • temp的有效索引范围是0 ~ temp_size-1,初始i = temp_size直接访问temp[temp_size]属于越界写入,破坏堆结构。
    • size_t是无符号整数类型,当i减到0时,i--会变成SIZE_MAX(无符号整数溢出),导致循环无法终止,进一步疯狂破坏内存。

另外,insert中temp[index - 1] = value的写法存在风险:如果用户传入index=0,index-1会变成SIZE_MAX,再次触发越界。

修复建议

  • 替换malloc/free为new/delete:C模板类应优先使用C内存管理方式,对于非POD类型,malloc不会调用构造函数,会导致对象未初始化。
  • 修正insert的循环逻辑:
    • 拷贝原数组元素时,循环上限改为array_size,而非temp_size。
    • 元素后移的循环从temp_size-1开始,到index结束(建议统一使用0-based索引,避免混淆)。
    • 对传入的index做合法性检查,避免越界访问。

内容的提问来源于stack exchange,提问作者NaturalDemon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:07:02