【问题标题】:How to get rid of Segmentation fault (core dumped)如何摆脱分段错误(核心转储)
【发布时间】:2021-09-28 18:05:09
【问题描述】:

我是 Linux 和 C 的新手。目前我正在尝试创建游戏“机器人”,现在我遇到了分段错误(核心转储)。 我已经用谷歌搜索过了,但是因为我是 Linux/C 的新手,所以我不太了解,也不知道什么是正确的,什么是错误的。

如果有人可以帮助我解决问题并给我一些我不必每次都问的提示,那将是非常好的..

#include <stdio.h>
#include <stdlib.h>

int x; //row
int y; //column
int robots;
int walls;
char playfield[0][0];

int main(int argc, char *argv[]) {

    printf("Enter the size of the Y-Axis! It should be bigger that 5 and lower that 75!\n");
    printf("It is recommended that you use uneven numbers!\n");
    scanf("%i", &x);
    if(x > 75 || x < 5) {
        printf("Learn to read!\n");
        exit(0);
    }
    printf("Enter the size of the Y-Axis! It should be bigger that 5 and lower that 75!\n");
    printf("It is recommended that you use uneven numbers!\n");
    scanf("%i", &y);
    if(y > 75 || y < 5) {
        printf("Learn to read!\n");
        exit(0);
    }
    printf("Enter the amount of walls!\n");
    scanf("%i", &walls);
    printf("Now enter the amount of robots!\n");
    scanf("%i", &robots);

    playfield[x][y], "\0";

    //Sets the value of every char in the [][] to '-'
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            playfield[i][j] = '-';
        }
    }

    playfield[x/2][y/2] = 'O'; //Gets the spawnpoint of the player
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            printf("%c ", playfield[i][j], "\0");
        }
        printf("\n");
    }

    placeObjects(walls, '#');

    return 0;
}

//Spawns walls and robots
void placeObjects(int amountOfObjs, char Obj) {
    int ObjX = rand() % (x + 1);
    int ObjY = rand() % (y + 1);
    for(int i = 0; i <= amountOfObjs; i++) {
        int ObjX = rand() % (x + 1);
        int ObjY = rand() % (y + 1);
        if(playfield[ObjX][ObjY] == '-') { 
            playfield[ObjX][ObjY] = Obj;
        } else {
            i--;
        }
    }
}

【问题讨论】:

  • char playfield[0][0];
  • char playfield[0][0]; 是如何编译的?没有警告吗? playfield[x][y], "\0"; 应该做什么?
  • 还有另外两个警告:printf("%c ", playfield[i][j], "\0"); 参数与说明符不匹配,函数placeObjects() 缺少声明。您确实必须启用并处理编译器警告。
  • 为什么不使用make CFLAGS="-Wall -g" your_program 构建您的程序,然后使用gdb your_program 运行它。如果出现错误,请使用 gdb 的 bt(回溯)查看问题所在。您可以使用frame #(其中# 是数字)切换到正确的框架,并使用info locals 检查局部变量。
  • 编译时,始终启用警告,然后修复这些警告。对于gcc,至少使用:gcc -c -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 yoursource name.c -o yoursourcename.o 然后当您纠正所有警告后,再使用gcc -ggdb yoursourcename.o -o yoursourcename

标签: c linux segmentation-fault coredump gentoo


【解决方案1】:

您静态声明了 1x1 矩阵 - 并且您尝试将值设置为 1x1 以上。 因此将第 6 行更改为:

char playfield[70][70] 

你有一些额外的警告 - 尝试摆脱它们。 与此同时,这是我得到的:

【讨论】:

【解决方案2】:

数组playfield 被声明为零元素,不允许访问其中的任何元素。

由于xy 的最大允许值是有限的,您可以静态分配足够的数组元素。

char playfield[76][76];

xy 的最大允许值为 75,ObjXObjY 最多分别为 xy,因此您至少需要 76 个元素)

另一种方式是根据输入的xy动态分配一些元素。

可以这样做:

char** playfield;

int main(int argc, char *argv[]) {

    /* ... */

    /* allocate buffer for y * x elements */
    char* buffer = malloc(sizeof(*buffer) * y * x);
    if (buffer == NULL) return 1;
    /* allocate buffer for x pointers for each row */
    playfield = malloc(sizeof(*playfield) * x);
    if (playfield == NULL) return 1;
    /* assign pointers to each row */
    for (int i = 0; i < x; i++) {
        playfield[i] = buffer + y * i;
    }

    /* ... */

    /* de-allocate what are allocated (for satisfying checkers like Valgrind) and exit */
    free(buffer);
    free(playfield);
    return 0;
}

【讨论】:

    猜你喜欢
    • 2015-06-25
    • 2021-06-03
    相关资源
    最近更新 更多