繁体   English   中英

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

[英]Segmentation Fault when resizing 2d vectors

我正在尝试制作一块瓷砖,但由于分段错误,memory 不断被丢弃。 如果板上没有足够的空间,当我尝试扩展板(在扩展板上 function 并调整矢量大小)时,会发生分段故障。 这是开发板的实现,它是 header 文件。 当我尝试调整内部向量的大小时,会发生分段错误。 板子.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;
}

板子.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

瓷砖.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;
};

瓷砖代码.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

瓷砖.cpp


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

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

驱动程序.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();
    

}

那么我是否必须重新分配更多 memory 或者我在调整大小时做错了什么? 谢谢

以下是我为编译代码所做的更改。 它们被记录为注释。

板子.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

板子.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:

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

我不知道 output 是否是您想要的,我确实更改了我在Board::addPiece()中发现的一个逻辑错误,但还有其他可能。 我还建议使用更好的样式以使您的代码更易于阅读。

我还建议您远离 C-isms,尤其是当您已经在使用卓越的 C++ 替代品时。

暂无
暂无

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

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