首页 > 解决方案 > 数组很大时出现 std::fill 分段错误错误

问题描述

我有以下类,它类似于二维的标量场,但由于可以使用周期性边界条件,因此也存在鬼区(简单地将其视为 2D 矩阵)。

#include <algorithm>
#include <iostream>
#include <fftw3.h>

class RectMesh
{
private:

  int cols_x;
  int rows_y;
  int nghost;
  double* mesh;

public:

  void CheckConstr(int& cols, int& rows, int& ghost);
  RectMesh(int cols=2, int rows=2, int ghost=1);

  /* Rule of 5 */
  ~RectMesh();
  RectMesh(const RectMesh& obj);
  RectMesh(RectMesh&& tmp) noexcept;
  RectMesh& operator=(RectMesh rhs);
  RectMesh& operator=(RectMesh&& tmp);
  
};

构造函数实现是

/*--------------------- Constructor -----------------------------*/
void RectMesh::CheckConstr(int& cols, int& rows, int& ghost)
{
  if (cols < 2 || rows < 2 || ghost < 0)
    {
      std::cout << "The smallest mesh must have dimensions (2x2)"
    "and the minimum number of ghost points is zero. Exiting."
        << std::endl; 
      exit(EXIT_FAILURE);
    }
}

RectMesh::RectMesh(int cols, int rows, int ghost)
  : cols_x(cols), rows_y(rows), nghost(ghost), mesh(nullptr)
{
  CheckConstr(cols,rows,ghost);
  int len = (cols_x+2*nghost)*(rows_y + 2*nghost);
  mesh = (double*) fftw_malloc(len*sizeof(double));
  std::fill(mesh, mesh+len, 0.0);
  std::cout << "RectMesh constructor called." << std::endl;
}

主功能

int main()
{
  int cols = 1e6;
  int rows = 1e6;
  int nghost = 2;
  RectMesh A(cols,rows,nghost);
  return 0;
}

控制台输出: Segmentation fault (core dumped)

当我注释掉std::fill或当我有时,这不会发生rows = cols = 1e5

这是为什么?

标签: c++arraysfill

解决方案


int len = (cols_x+2*nghost)*(rows_y + 2*nghost);

将 1e6 插入cols_xrows_y,将 2插入nghost,然后将最终结果乘以sizeof(double)8,总计为:

8000064000128

字节,或您尝试分配的超过 7 TB 的内存。这里发生了两件事之一:

  1. fftw_malloc对此大笑,然后返回NULL,并且您显示的代码无法检查其返回值,并发现没有分配任何内容,或者

  2. 实际的乘法溢出(如果在 32 位平台上),结果同样荒谬。


推荐阅读