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

如何在二维数组的拷贝构造与赋值运算符中使用memcpy?

如何在两种二维float数组实现类中使用memcpy完成拷贝构造与赋值重载

因为float是POD(普通旧数据)类型,内存布局简单可直接拷贝,所以完全可以用std::memcpy替代逐元素循环赋值,提升拷贝效率。以下针对两个类分别说明实现方式:


一、UsingPtrToArr类(指向固定宽度数组的指针)

该类的二维数组是连续内存块,new float[m_rows][8]会分配一块连续的内存空间,所有行数据依次排布,因此可以直接一次性拷贝整个数组内存。

修改后的拷贝构造函数

UsingPtrToArr(const UsingPtrToArr& iv) {
  m_rows = iv.m_rows;
  f = new float[m_rows][8];
  // 一次性拷贝所有行数据,内存连续无需逐行处理
  std::memcpy(f, iv.f, m_rows * 8 * sizeof(float));
  sum = iv.sum;
}

修改后的赋值运算符重载

注意:必须先处理自赋值,再释放旧内存,避免内存泄漏与悬挂指针

UsingPtrToArr& operator= (const UsingPtrToArr& iv) {
  if (this == &iv) return *this; // 防止自赋值

  // 释放旧内存
  delete[] f;

  m_rows = iv.m_rows;
  f = new float[m_rows][8];
  std::memcpy(f, iv.f, m_rows * 8 * sizeof(float));
  sum = iv.sum;
  return *this;
}

二、UsingPtrToPtr类(指向指针的指针)

该类的每行内存是独立分配的,指针数组f中存储的是每行内存的地址,整个二维数组的内存不连续,因此只能逐行使用memcpy拷贝。

修正并修改后的拷贝构造函数

原代码循环从i=1开始会遗漏第一行数据,需改为从i=0开始:

UsingPtrToPtr(const UsingPtrToPtr& iv) {
  sum = iv.sum;
  m_rows = iv.m_rows;
  m_cols = iv.m_cols;
  f = new float*[m_rows];
  for(int i = 0; i < m_rows; ++i) {
    f[i] = new float[m_cols];
    // 逐行拷贝连续的列数据
    std::memcpy(f[i], iv.f[i], m_cols * sizeof(float));
  }
}

修正并修改后的赋值运算符重载

同样需要处理自赋值与旧内存释放,同时修正原代码中释放内存的循环起始错误:

UsingPtrToPtr& operator= (const UsingPtrToPtr& iv) {
  if (this == &iv) return *this; // 自赋值检查

  // 释放旧内存:必须遍历所有行
  for (int i = 0; i < m_rows; ++i) {
    delete[] f[i];
  }
  delete[] f;

  // 分配新内存并逐行拷贝
  m_rows = iv.m_rows;
  m_cols = iv.m_cols;
  f = new float*[m_rows];
  for(int i = 0; i < m_rows; ++i) {
    f[i] = new float[m_cols];
    std::memcpy(f[i], iv.f[i], m_cols * sizeof(float));
  }
  sum = iv.sum;
  return *this;
}

关键注意事项

  • 仅当元素类型为POD时,使用memcpy才安全。float属于POD,若替换为自定义非POD类型(如包含自定义构造/析构函数的类),memcpy会导致浅拷贝,引发未定义行为。
  • 赋值运算符必须处理自赋值场景,否则会在释放旧内存后导致自身数据丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:55:29