当我 运行 以下代码时出现分段错误/故障
I am getting segmentation error /fault when I run the below code
我是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();
}
使用 gcc -g -fsanitize=address a.c && ./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
。
此处出现无限循环导致数组边界异常。原因是赋值语句没有执行。
while (unvisitedVertex = getAdjUnvisitedVertices(tempVertex) != -1)
为确保赋值操作与条件运算符一起发生,需要用括号括起来。
while ((unvisitedVertex = getAdjUnvisitedVertices(tempVertex)) != -1)
这个变化的结果是
广度优先遍历:
SABCD
我是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();
}
使用 gcc -g -fsanitize=address a.c && ./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
。
此处出现无限循环导致数组边界异常。原因是赋值语句没有执行。
while (unvisitedVertex = getAdjUnvisitedVertices(tempVertex) != -1)
为确保赋值操作与条件运算符一起发生,需要用括号括起来。
while ((unvisitedVertex = getAdjUnvisitedVertices(tempVertex)) != -1)
这个变化的结果是 广度优先遍历: SABCD