【问题标题】:I am getting segmentation error /fault when I run the below code运行以下代码时出现分段错误/错误
【发布时间】:2021-12-28 07:23:24
【问题描述】:

我是 C 新手。在在线 C 编译器中运行以下图形遍历算法程序时出现分段错误。我知道错误是由于访问了尚未初始化或无法访问的内存,但我不知道错误发生在哪里。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define max 5
struct vertex{
    char name;
    bool isVisited;
};
int queue[max];
int rear = -1, front = 0, queueCount = 0, vertexCount = 0;
struct vertex* adjList[max];
int adjMat[max][max];
void insert(int data){
    queue[++rear] = data;
    queueCount++;
}
int delete(){
    queueCount--;
    return queue[front++];
}
bool isEmpty(){
    return queueCount == 0;
}
void addVertex(char name){
    struct vertex* v = (struct vertex*)malloc(sizeof(struct vertex));
    v->name = name;
    v->isVisited = false;
    adjList[vertexCount++] = v;
}
void addEdge(int start, int end){
    adjMat[end][start] = 1;
    adjMat[start][end] = 1;
}
void display(int vertexIndex){
    printf("%c", adjList[vertexIndex]->name);
}
int getAdjUnvisitedVertices(int vertexIndex){
    for (int i = 0; i < vertexCount; i++){
        if (adjMat[vertexIndex][i] == 1 && adjList[i]->isVisited == false){
            return i;
        }
    }
    return -1;
}
void BFS(){
    adjList[0]->isVisited = true;
    display(0);
    insert(0);
    int unvisitedVertex;
    while (!isEmpty()){
        int tempVertex = delete();
        while (unvisitedVertex = getAdjUnvisitedVertices(tempVertex) != -1){
            adjList[unvisitedVertex]->isVisited = true;
            display(unvisitedVertex);
            insert(unvisitedVertex);
        }
    }
    for (int i = 0; i < vertexCount; i++){
        adjList[i]->isVisited = false;
    }
}
void main(){
    for (int i = 0; i < max; i++){
        for (int j = 0; j < max; j++){
            adjMat[i][j] = 0;
        }
    }
    addVertex('S');
    addVertex('A');
    addVertex('B');
    addVertex('C');
    addVertex('D');
    addEdge(0,1);
    addEdge(0,2);
    addEdge(0,3);
    addEdge(1,4);
    addEdge(2,4);
    addEdge(3,4);
    printf("Breadth First Traversal : ");
    BFS();
}

【问题讨论】:

  • 使用调试器查找错误发生的位置。
  • @kiner_shah 我不知道如何使用调试器,因为我是 C 新手
  • 哪个 IDE?哪个操作系统?
  • 我尝试了许多编译器,如 OnlineGDB、tutorialspoint IDE、OneCompiler 和 programiz。全部显示分段错误或 SIGSEGV 错误和监控的命令转储核心错误
  • 在线 GDB 上有一个调试代码的选项。但是,是的,我认为您可能会面临学习如何使用它的困难(它是 GDB)。

标签: c memory graph segmentation-fault runtime-error


【解决方案1】:

使用 gcc -g -fsanitize=address a.c &amp;&amp; ./a.out 会导致:

=================================================================
==2590725==ERROR: AddressSanitizer: global-buffer-overflow on address 0x563fc7b38394 at pc 0x563fc7b35262 bp 0x7ffe7e7fd600 sp 0x7ffe7e7fd5f8
WRITE of size 4 at 0x563fc7b38394 thread T0
    #0 0x563fc7b35261 in insert /tmp/a.c:14
    #1 0x563fc7b35839 in BFS /tmp/a.c:55
    #2 0x563fc7b35a89 in main /tmp/a.c:80
    #3 0x7fe91f032e49 in __libc_start_main ../csu/libc-start.c:314
    #4 0x563fc7b35139 in _start (/tmp/a.out+0x1139)

0x563fc7b38394 is located 0 bytes to the right of global variable 'queue' defined in 'a.c:9:5' (0x563fc7b38380) of size 20
0x563fc7b38394 is located 44 bytes to the left of global variable 'front' defined in 'a.c:10:16' (0x563fc7b383c0) of size 4

第 14 行是:

     queue[++rear] = data;

所以在问题点,rear 索引超过了5。

【讨论】:

  • 您的意思是错误是由于我错误访问的队列和前端变量造成的吗?我对g++一无所知,所以要简单
  • @20CSE028AfsalBaaqirA,插入前检查队列是否已满,删除前检查队列是否已空。
  • @Employed Russian Umm 当我分别在 delete() 和 insert() 处检查 isEmpty() 和 isFull() 时,我得到了无限打印的字符(比如 A)。
【解决方案2】:

此处发生无限循环,导致数组边界异常。原因是赋值语句没有被执行。

 while (unvisitedVertex = getAdjUnvisitedVertices(tempVertex) != -1)

为确保赋值操作与条件运算符一起发生,需要用括号括起来。

while ((unvisitedVertex = getAdjUnvisitedVertices(tempVertex)) != -1)

有了这个改变的结果是 广度优先遍历: SABCD

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 2015-06-19
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多