【问题标题】:Segmentation Fault When Trying to Interact with a 2D Array C++尝试与 2D 数组 C++ 交互时出现分段错误
【发布时间】:2020-03-06 02:06:24
【问题描述】:

我正在尝试通过 Board 类与 2D 数组进行交互。但是,在运行包含此代码的主文件时,我遇到了分段错误:

#include "Board.h"

int main(int argc, char** argv)
{
  int height = 0;
  int width = 0;
  int pop_density = 0.8;

  Board* c = new Board(height,width);
  c->print();
  c->populate(pop_density);
  c->print();

  //for (i )
  cout << c->read_char_at_index(1,2) << endl;

  delete c;

  return 0;
}

这是 Board.cpp 代码:

#include "Board.h"

//in board: make a fucntion that pulls from file

Board::Board(int h, int w)
{
  m_height = h;
  m_width = w;
  m_array = new char* [m_height];
  for (int i = 0; i < m_height; ++i)
  {
    m_array[i] = new char[m_width];
    for (int j = 0; j < m_width; ++j)
    {
      m_array[i][j] = '-';
    }
  }
  cout << "Made board" << endl;
}

Board::~Board()
{
  for (int i = 0; i < this->m_height; ++i)
  {
    delete[] this->m_array[i];
  }
  delete[] this->m_array;

  cout << "Destructed Board" << endl;
}

void Board::print()
{
  for (int i = 0; i < this->m_height; ++i)
  {
    for (int j = 0; j < this->m_width; ++j)
    {
      cout << this->m_array[i][j] << " ";
    }
    cout << endl;
  }
}

void Board:: populate(double density)
{
  //seeding rand with time
  srand(time(NULL));
  int totalCells = this->m_height * this->m_width;
  int cellsToFill = round(totalCells * density);
  int cellsFilled = 0;

  for (int i = 0; i < cellsToFill; ++i)
  {
    int randomRow = rand() % this->m_height;
    int randomColumn = rand() % this->m_width;

    this->m_array[randomRow][randomColumn] = 'X';
  }
}

void Board:: write_char_at_index(int height, int width, char z)
{
  cout << "pre" << endl;
  cout << height << " " << width << endl;
  m_array[height][width] = z;
  cout << "Wrote" << endl;
}

char Board:: read_char_at_index(int height, int width)
{
  return m_array[height][width];
  cout << "read" << endl;
}

还有 Board.h 代码:

#ifndef BOARD_H
#define BOARD_H

#include <iostream>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;

//This class is used to make a Board object

class Board
{
  public:
    Board(int h, int w);
    ~Board();
    void print(); // Prints the board to cout
    void populate(double density); // Populates board based on density input
    void write_char_at_index(int height, int width, char z);
    char read_char_at_index(int height, int width);

  private:
    char** m_array; // 2D array dynamically allocated during runtime
    int m_height;
    int m_width;
};

#endif

任何帮助或建议都会很棒,因为我已经问过两个同学,他们不确定问题出在哪里。我确定我尝试将 char 值分配给的索引没有超出范围。

【问题讨论】:

  • 你传递给函数write_char_at_index的值是什么?有没有可能他们越界了?
  • 您可能会显式或无意地复制对象。如果是这样,默认构造函数将只复制 m_array 指针,然后原始对象被销毁并释放内存
  • 考虑生成minimal reproducible example,如果这没有指出错误及其解决方案,请编辑您的帖子并将代码替换为 MRE。
  • 由于您似乎依赖屏幕消息进行调试,我建议在析构函数中插入一条日志消息“ 内存刚刚被释放”。您很可能会在方法输出之前看到它。

标签: c++ pointers multidimensional-array segmentation-fault


【解决方案1】:

read_char_at_index的输入参数是main函数中的(1,2)。但是,Board 对象 c 的高度 = 0,宽度 = 0。您可以将高度和宽度的值修改为足够大的值,例如 10、10。

    int height = 10;
    int width = 10;
    int pop_density = 0.8;

    Board* c = new Board(height, width);
    c->print();
    c->populate(pop_density);
    c->print();

    cout << c->read_char_at_index(1, 2) << endl;

程序可以在没有分段错误的情况下运行。

注意:函数“write_char_at_index”和“read_char_at_index”可能会检查输入值(高度和宽度)以确保对 m_array 成员的访问是安全的。

    if (height >= this->m_height || width >= this->m_width)
    {
        return;
    }

【讨论】:

  • 旁注:Board* c = new Board(height, width);也可以是Board c(height, width);这里不需要动态分配。
  • 感谢您的 cmets。而且,在使用Board c(height, width);的情况下,对象c不会被手动删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 2019-09-03
  • 2015-08-27
相关资源
最近更新 更多