【问题标题】:qemu: uncaught target signal 11 (Segmentation fault) - core dumped Segmentation fault - EXC_BAD_ACCESS (code=2, address=0x16f603ff0)qemu:未捕获的目标信号 11(分段错误)- 核心转储分段错误-EXC_BAD_ACCESS(代码=2,地址=0x16f603ff0)
【发布时间】:2023-01-30 01:22:21
【问题描述】:

我需要用 5 个不同的项目随机填充这个二维数组。每个项目的数量在运行时以百分比形式传递,连同二维数组的维度。

这是我尝试过的,但我在终端中遇到了分段错误。当我尝试运行调试器时出现此错误:

EXC_BAD_ACCESS (code=2, address=0x16f603fe8)

.h文件

#ifndef LEVEL_H
#define LEVEL_H

#include <cmath>
#include <iostream>
#include <time.h>
#include <stdio.h>
#include "Mario.h"


using namespace std;

//Class for level
class Level{
public:
    //Constructor for level, which takes in the array dimensions
    //Also takes in the percentages chosen by the file, for how many coins, nothing spaces, goomba and koopa's
    //are present in the array (world)
    Level(int dimension, int coinPrct, int nothingPrct, int goombaPcrt, int koopaPrct, int mushPcrt);
    
    //Default destructor
    ~Level();

    void populate();

    char nextItem();
    
//Private member variables
private:
    char *m_levelAry;
    int m_coins;
    int m_nothing;
    int m_goombas;
    int m_koopas;
    int m_mushrooms;
    int m_dimension;
};

#endif

.cpp 文件

#include "Level.h"

//Constructor handles dimensions of the array and odds of how frequent coins, enemies and nothing spawn
Level::Level(int dimension, int coinPrct, int nothingPrct, int goombaPcrt, int koopaPrct, int mushPcrt){
    m_dimension = dimension;
    m_levelAry = new char [dimension * dimension];
    m_coins = round((coinPrct/100.0) * (dimension * dimension));
    m_nothing = round((nothingPrct/100.0) * (dimension * dimension));
    m_goombas = round((goombaPcrt/100.0) * (dimension * dimension));
    m_koopas = round((koopaPrct/100.0) * (dimension * dimension));
    m_mushrooms = round((mushPcrt/100.0) * (dimension * dimension));

    /*
    srand(time(NULL));
    
    for (int i = 0; i < dimension; i++){
        for (int j = 0; j < dimension; j++){
            m_levelAry[i * dimension + j] = nextItem();
        }
    }

    for (int i = 0; i < dimension; i++){
        for (int j = 0; j < dimension; i++){
            cout << m_levelAry[i * dimension + j] << " ";
        }
        cout << endl;
    }
    */
}

Level::~Level(){
    delete[] m_levelAry;
}

void Level::populate(){
    srand(time(NULL));
    
    for (int i = 0; i < m_dimension; i++){
        for (int j = 0; j < m_dimension; j++){
            m_levelAry[i * m_dimension + j] = nextItem();
        }
    }

    for (int i = 0; i < m_dimension; i++){
        for (int j = 0; j < m_dimension; i++){
            cout << m_levelAry[i * m_dimension + j] << " ";
        }
        cout << endl;
    }
}


char Level::nextItem(){
    int randItemNum = (rand() % 4) + 1;
    switch (randItemNum){
        case 1:
            if (m_coins != 0){
                m_coins -= 1;
                return 'c';
            } else {
                return nextItem();
            }
            break;
        case 2:
            if (m_nothing != 0){
                m_nothing -= 1;
                return 'x';
            } else {
                return nextItem();
            }
            break;
        case 3:
            if (m_goombas != 0){
                m_goombas -= 1;
                return 'g';
            } else {
                return nextItem();
            }
            break;
        case 4:
            if (m_koopas != 0){
                m_koopas -= 1;
                return 'k';
            } else {
                return nextItem();
            }
            break;
        case 5:
            if (m_mushrooms != 0){
                m_mushrooms -= 1;
                return 'm';
            } else {
                return nextItem();
            }
            break;
        default:
            return NULL;
            break;
    }
}

int main(int argc, char const *argv[])
{
    Level level1(5, 25, 47, 8, 8, 12);
    level1.populate();
    return 0;
}

【问题讨论】:

  • 请阅读 tour 到最后,并在我们的 help center 告诉自己您可以在这里问什么以及如何问。
  • 好的谢谢。现在好点了吗?
  • 不,不是,怎么会呢?因为我只是为您编辑了普通的废话不可运行的代码 sn-ps?
  • 调试器应该已将您指向导致错误的代码行。您是否尝试过使用调试器逐行逐行执行代码,查看每一步的变量,并验证计算是否在每一步产生您期望的结果?
  • 建议:read up on the Rule of Three和m_coins = round((coinPrct/100.0) * (dimension * dimension));考虑改为m_coins = coinPrct * dimension * dimension / 100;这里可能不需要浮点数。最后再分吧。

标签: c++


【解决方案1】:

Level::nextItem() 中的 switch case 永远不会进入 case 5。

int randItemNum = (rand() % 4) + 1;的范围是1~4。

当m_coins、m_nothing、m_goobas、m_koopas全部消耗完后,Level::nextItem()会死循环,最后会导致segmentation fault。

注:gdb对处理此类问题很有帮助。

【讨论】:

  • 旁注:这不是使用递归的特别好或安全的地方。不过,确实帮助找到了一个错误。
【解决方案2】:

更简单、更安全的人群:

void Level::populate(){
// starting at the beginning of the array, load it up with the computed 
// numbers of different tiles
    char *locp = m_levelAry;
    memset(locp, m_coins, 'c');
    locp += m_coins;
    memset(locp, m_goombas, 'g');
    locp += m_goombas;
    memset(locp, m_koopas, 'k');
    locp += m_koopas;
    memset(locp, m_mushrooms, 'm');
    locp += m_mushrooms;
    memset(locp, m_nothing, 'x');
    locp += m_nothing; // locp now points to the end of the array, 
                       // assuming enough tiles were generated. Buffer 
                       // overflow if rounding went askew and too many items 
                       // generated.
// set up random number generation 
    std::random_device rd;
    std::mt19937 engine(rd());
// shuffle all of the tiles.
    std::shuffle(m_levelAry, locp, engine);
}

代码用每个图块的所需数量填充数组,然后打乱数组以获得良好的图块分布。

旁注:我会计算硬币、koopas、goombas 和蘑菇的数量。没有什么会是数组中的剩余空间。这可以防止出现数学运算不能完全填满数组的问题。

【讨论】:

    猜你喜欢
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 2021-07-24
    • 2022-10-13
    • 1970-01-01
    • 2018-04-03
    • 2023-01-31
    相关资源
    最近更新 更多