简体   繁体   English

调整二维向量大小时出现分段错误

[英]Segmentation Fault when resizing 2d vectors

I'm trying to make a board of tiles, but the memory keeps getting dumped due to a segmentation fault.我正在尝试制作一块瓷砖,但由于分段错误,memory 不断被丢弃。 The segmentaiton fault occurs when I try to expand the board (on the expandboard function and resizing the vector), if there is not enough space on the board.如果板上没有足够的空间,当我尝试扩展板(在扩展板上 function 并调整矢量大小)时,会发生分段故障。 Here is the implementation of the board and it's header files.这是开发板的实现,它是 header 文件。 The segmentation fault occurs when I'm trying to resize the inner vector.当我尝试调整内部向量的大小时,会发生分段错误。 Board.cpp板子.cpp

#include "Board.h"
#include <malloc.h>
Board::Board(){
    this->board={{"--","--"},{"--","--"}};
    int letterarraylength =26;
    this->letterarray[letterarraylength]={};
    int initletarray[]={'A','B','C','D','E','F','G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 
    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'Y', 'X', 'Z'};
    
    for(int i=0; i<letterarraylength; i++){
        this->letterarray[i]=initletarray[i];
    }
    
}

void Board::expandBoard(int row, int columns){
    this->board.resize(row);
     int boardsize = this->board.size();
     for (int i=0; i<boardsize; i++){
         try{
            this->board[i].reserve(columns);
            this->board[i].resize(columns,"--");
         }catch(std::bad_alloc &e){
           cout << "Memory allocation fail!" << std::endl;
         }
        
    }
    this->rows = row;
    this->cols = columns;
}
void Board::addPiece(Tile *tile, string Coodinate){
     string output ="";
     int c = tile->colour;
     string shape= std::to_string(c); //Issue on converting colour to an int, leading to erroneous double digit ints?
     output=+ tile->colour;
     output= output +shape;
     
     int Cl = Coodinate[1]-'0';
     Cl = Cl-1;
     char R = Coodinate[0];
     int Rw = getRowByChar(R);
     
     if (Cl == this->cols-1){
         expandBoard(this->rows, Cl+2);
         this->board[Rw][Cl]=output;
     } else if (Rw==this->rows-1){
         expandBoard(Rw+2, this->cols);
         this->board[Rw][Cl]=output;
     } else if (Rw== this->rows-1 && Cl ==this->cols-1){
         expandBoard(Rw+2, Cl+2);
         this->board[Rw][Cl]=output;
     } else if (Rw > this->rows-1 || Cl > this->cols-1){
         cout<< "Unable to Add Piece, Placement out of bounds" << std::endl;
     } else {
         this->board[Rw][Cl]=output;
     }

}

int Board::getRowByChar(char r){
    int rowInt =0;
    for (int i=rowInt ; i<26 ; i++){
        if(this->letterarray[i]==r){
            rowInt=i;
        }
    }

    return rowInt;
}

char Board:: getRowasChar(int row){
    char returnChar='A';
    for(int i=0; i<26;i++){
        if (row==this->letterarray[i]){
            returnChar=this->letterarray[i];
        }
    }

    return returnChar;

}


int Board::getRow(){
    return this->rows;
}

int Board::getColumn(){
    return this->cols;
}


void Board::printBoard(){
    int rows = this->board.size();
        for (int i=0; i< rows ; i++){
            int cols = this->board[i].size();
       for (int j=0; j <cols ; j++){
           std::cout<<this->board[i][j] << " | " ;
       }
       std::cout <<std::endl;
   }
        
}

string Board::getBoardString(){
    string output ="";
    int rows = this->board.size();
    for (int i=0; i<rows ;i++){
      int cols =this->board[i].size();
      for(int j=0; j<cols ;j++){
          if(this->board[i][j]!="--"){
              string combined="";
              string piece = this->board[i][j];
              char rowChar = getRowasChar(i);
              string position = rowChar + std::to_string(j);
              combined =piece + "@"+position;
              output += combined+",";
          }
      }

      
    }

    output.pop_back();
    return output;
}

Board.h板子.h

#ifndef ASSIGN2_BOARD_H
#define ASSIGN2_BOARD_H
#include "Tile.h"
#include <iostream>
#include <vector>
#include <map>
using std::cout; 
using std::vector; 
using std::map;
using std::string;
class Board{
    public:
        Board();
        void printBoard();
        void addPiece(Tile *tile, string Coodinate);
        void expandBoard(int row, int column);
        string getBoardString();
        int getRow();
        int getColumn();
    private: 
        int getRowByChar(char r);
        char getRowasChar(int row);
        vector<vector<string> >board;
        
        int rows=2;
        int cols=2;
        char letterarray[];
};


#endif

Tile.h瓷砖.h


#ifndef ASSIGN2_TILE_H
#define ASSIGN2_TILE_H
#include "TileCodes.h"
// Define a Colour type
typedef char Colour;

// Define a Shape type
typedef int Shape;

class Tile {
public:
   Tile(Colour col, Shape shape);
   void printTile();
   Colour colour;
   Shape  shape;
};

Tilecodes.h瓷砖代码.h


#ifndef ASSIGN1_TILECODES_H
#define ASSIGN1_TILECODES_H

// Colours
#define RED    'R'
#define ORANGE 'O'
#define YELLOW 'Y'
#define GREEN  'G'
#define BLUE   'B'
#define PURPLE 'P'

// Shapes
#define CIRCLE    1
#define STAR_4    2
#define DIAMOND   3
#define SQUARE    4
#define STAR_6    5
#define CLOVER    6

#endif // ASSIGN1_TILECODES_H

Tile.cpp瓷砖.cpp


Tile::Tile(Colour col, Shape shape){
    this->colour = col;
    this->shape = shape;
}

void Tile::printTile(){
    std::cout << this->colour << this -> shape;
}

driver.cpp驱动程序.cpp

#include "Board.h"
#include <iostream>
int main(void){
    Board * bd = new Board();
    Tile * td1 = new Tile(RED,CIRCLE);
    Tile * td2 = new Tile(BLUE,DIAMOND);
    Tile * td3 = new Tile(YELLOW,SQUARE);
    Tile * td4 = new Tile(ORANGE, CLOVER);
    bd->addPiece(td1, "A1");
    bd->addPiece(td2, "B1");
    bd->addPiece(td3, "C1");
    bd->addPiece(td4, "C2");
    bd->printBoard();
    

}

So do i have to reallocate more memory or what have i done wrong with the resizing?那么我是否必须重新分配更多 memory 或者我在调整大小时做错了什么? Thanks谢谢

Below are the changes I made that got the code to compile.以下是我为编译代码所做的更改。 They are noted as comments.它们被记录为注释。

Board.h板子.h

#ifndef ASSIGN2_BOARD_H
#define ASSIGN2_BOARD_H
#include <iostream>
#include <vector>

#include "Tile.hpp"
// #include <map>  // CHANGED: Not used, but a good idea for the alphabet
#include <string>  // CHANGED: Include what you use

// using std::cout;  // CHANGED: Not where you'd put this; make them more local
// using std::vector;
// using std::map;
// using std::string;
class Board {
 public:
  Board() = default;
  void printBoard();
  void addPiece(Tile *tile, std::string Coodinate);
  void expandBoard(int row, int column);
  std::string getBoardString();
  int getRow();
  int getColumn();

 private:
  int getRowByChar(char r);
  char getRowasChar(int row);
  std::vector<std::vector<std::string> > board{{"--", "--"}, {"--", "--"}};

  int rows = 2;
  int cols = 2;
  char letterarray[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                        'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                        'S', 'T', 'U', 'V', 'W', 'Y', 'X', 'Z'};
};

#endif

Board.cpp板子.cpp

#include "Board.hpp"
// #include <malloc.h>  // CHANGED: WHY?

// CHANGED: Don't need to write default constructor if you use default member
// initialization

void Board::expandBoard(int row, int columns) {
  this->board.resize(row);
  int boardsize = this->board.size();
  for (int i = 0; i < boardsize; i++) {
    try {
      // this->board[i].reserve(columns);  // CHANGED: Unnecessary
      this->board[i].resize(columns, "--");
    } catch (std::bad_alloc &e) {
      std::cout << "Memory allocation fail!" << std::endl;
    }
  }
  this->rows = row;
  this->cols = columns;
}

void Board::addPiece(Tile *tile, std::string Coodinate) {
  std::string output = "";
  int c = tile->colour;
  std::string shape =
      std::to_string(c);  // Issue on converting colour to an int, leading to
                          // erroneous double digit ints?
  output = +tile->colour;
  output = output + shape;

  int Cl = Coodinate[1] - '0';
  Cl = Cl - 1;
  char R = Coodinate[0];
  int Rw = getRowByChar(R);

  if (Rw == this->rows - 1 && Cl == this->cols - 1) {  // CHANGED: Swapped order
    expandBoard(this->rows, Cl + 2);
    this->board[Rw][Cl] = output;
  } else if (Rw == this->rows - 1) {
    expandBoard(Rw + 2, this->cols);
    this->board[Rw][Cl] = output;
  } else if (Cl == this->cols - 1) {
    expandBoard(Rw + 2, Cl + 2);
    this->board[Rw][Cl] = output;
  } else if (Rw > this->rows - 1 || Cl > this->cols - 1) {
    std::cout << "Unable to Add Piece, Placement out of bounds" << std::endl;
  } else {
    this->board[Rw][Cl] = output;
  }
}

int Board::getRowByChar(char r) {
  int rowInt = 0;
  for (int i = rowInt; i < 26; i++) {
    if (this->letterarray[i] == r) {
      rowInt = i;
    }
  }

  return rowInt;
}

char Board::getRowasChar(int row) {
  char returnChar = 'A';
  for (int i = 0; i < 26; i++) {
    if (row == this->letterarray[i]) {
      returnChar = this->letterarray[i];
    }
  }

  return returnChar;
}

int Board::getRow() { return this->rows; }

int Board::getColumn() { return this->cols; }

void Board::printBoard() {
  int rows = this->board.size();
  for (int i = 0; i < rows; i++) {
    int cols = this->board[i].size();
    for (int j = 0; j < cols; j++) {
      std::cout << this->board[i][j] << " | ";
    }
    std::cout << std::endl;
  }
}

std::string Board::getBoardString() {
  std::string output = "";
  int rows = this->board.size();
  for (int i = 0; i < rows; i++) {
    int cols = this->board[i].size();
    for (int j = 0; j < cols; j++) {
      if (this->board[i][j] != "--") {
        std::string combined = "";
        std::string piece = this->board[i][j];
        char rowChar = getRowasChar(i);
        std::string position = rowChar + std::to_string(j);
        combined = piece + "@" + position;
        output += combined + ",";
      }
    }
  }

  output.pop_back();
  return output;
}

Output: Output:

R82 | -- | -- | 
B66 | -- | -- | 
Y89 | O79 | -- | 
-- | -- | -- |

I don't know if the output is what you want, I did change one logic error that I spotted in Board::addPiece() , but there is a possibility of others.我不知道 output 是否是您想要的,我确实更改了我在Board::addPiece()中发现的一个逻辑错误,但还有其他可能。 I also recommend better styling to make your code easier to read.我还建议使用更好的样式以使您的代码更易于阅读。

I also recommend getting away from C-isms, especially when you're using the superior C++ alternatives already.我还建议您远离 C-isms,尤其是当您已经在使用卓越的 C++ 替代品时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM