C 循环时链表中的分段错误?
我正在尝试用C语言设置一个图形。我尝试了使用用户输入的图形,它工作得非常好。但是,我正在尝试实现从文件读取。最后一条else语句是错误的来源,因为当我注释掉它时,它编译起来没有任何问题。我已经包括了一个评论块,我认为这有问题。如果这个问题还需要什么,请告诉我C 循环时链表中的分段错误?,c,C,我正在尝试用C语言设置一个图形。我尝试了使用用户输入的图形,它工作得非常好。但是,我正在尝试实现从文件读取。最后一条else语句是错误的来源,因为当我注释掉它时,它编译起来没有任何问题。我已经包括了一个评论块,我认为这有问题。如果这个问题还需要什么,请告诉我 #include <stdio.h> #include <stdlib.h> struct node{ int data; struct node* next; }; //int counter
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node* next;
};
//int counter and mainVertex would be used to determine if graph is connected.
// void graphConnection(){
//
//
//
//
//
//
// }
char* deblank(char* input)
{
int i,j;
char *output=input;
for (i = 0, j = 0; i<strlen(input); i++,j++)
{
if (input[i]!=' ')
output[j]=input[i];
else
j--;
}
output[j]=0;
return output;
}
struct node *G[1000];
int counter = 0;
char *mainVertex;
void readingEachLine(){
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
//Read file and exit if fail
fp = fopen("test.txt", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, fp)) != -1) {
line = deblank(line);
int i = 0;
struct node* cursor = malloc(sizeof(struct node));
struct node* secondcursor = malloc(sizeof(struct node));
struct node* tempitem;
while(line[i] != '\n'){
//If its the first of the line look into the array and set struct cursor to the corresponding
//array position
if (i == 0){
mainVertex[counter] = line[0];
int convertor = line[i] - '0';
cursor = G[convertor];
counter++;
}
//if its not the first, then set a struct with that number as data
else{
tempitem = malloc(sizeof(struct node));
int convertor = line[i] - '0';
tempitem->data = convertor;
tempitem->next = NULL;
}
//if there is no element connected to the struct in array, connect the tempitem
if (cursor->next == NULL){
cursor->next = tempitem;
}
//If there are already connected elements, loop until the end of the linked list
//and append the tempitem
//ERROR: I GET SEGMENTATION FAULT FROM HERE. TRIED AFTER COMMENTING IT OUT
else{
secondcursor = cursor;
while(secondcursor->next != NULL){
secondcursor = secondcursor->next;
}
secondcursor->next = tempitem;
}
i++;
}
printf("\n");
}
}
int main(void){
for (int i = 1; i < 1000; i++)
{
G[i]= malloc(sizeof(struct node));
G[i]->data = i;
G[i]->next = NULL;
}
readingEachLine();
}
您的代码有几个错误选项:
- 显然,最多可以有1000个节点。您有一个包含1000个指向链接列表的头指针的数组
。不要在开始时为所有1000个节点分配内存。在开始时,所有列表都是空的,空链表是一个没有节点且其头为G
的列表NULL
- 在您的示例中,
用于迭代已经存在的指针,所以不要为它分配内存。如果您有这样的代码:cursor
你不应该分配。您将覆盖struct node *p = malloc(...); // next use of p: p = other_node;
,并丢失分配内存的句柄。并非所有指针都必须用p
初始化;仅在创建节点时分配malloc
- 如果有超过9个节点,那么从一行中去掉所有空格然后解析单个数字的想法将失败。(但你需要1000个节点)不要试图自己解析这些数字。有用于此的库函数,例如
strtol
- 尚不清楚什么是
。当指定给它时,只能使用它一次。您将其视为一个数组,但它是一个全局指针,初始化为mainVertex
。当您取消引用它时,您会得到未定义的行为,这就是您的分段错误可能来自的地方NULL
#包括
#包括
#包括
枚举{
最大节点数=1000
};
结构节点{
int数据;
结构节点*下一步;
};
结构节点*G[maxNodes];
大小n节点=0;
int read_图(常量字符*fn)
{
文件*fp;
char*line=NULL;
尺寸长度=0;
fp=fopen(fn,“r”);
if(fp==NULL)返回-1;
while(getline(&line,&len,fp)!=-1){
char*p;
字符*结束;
int-id;
int n;
id=strtol(第10行和第10行);
如果(结束==行)继续;
如果(id<1 | | id>maxNodes)中断;
如果(id>nnode)nnode=id;
id--;
p=结束;
n=strtol(p和end,10);
while(p!=结束){
结构节点*nnew=malloc(sizeof(*nnew));
nnew->data=n-1;
nnew->next=G[id];
G[id]=nnew;
p=结束;
n=strtol(p和end,10);
}
}
fclose(fp);
自由线;
返回0;
}
内部主(空)
{
如果(读取图表(“test.txt”)<0){
fprintf(stderr,“无法生成图形。\n”);
出口(1);
}
对于(int i=0;inext){
printf(“%d”,p->data+1);
}
认沽权(“”);
}
}
对于(int i=0;inext;
免费(旧);
}
}
返回0;
}
OT:关于:if(fp==NULL)退出(退出失败)代码>这会导致程序退出,而不会向用户提供任何发生情况的指示。建议:if(fp==NULL){perror(“fopen失败”);exit(exit_FAILURE)}
,因为调用perror()
将输出到stderr
您的错误消息和系统认为错误发生的文本原因。,OT:调用任何堆分配函数时:malloc
calloc
realloc
1)始终检查(!=NULL)返回值以确保操作成功。是否可以在回答中发布这些值?非常好的建议,希望解释代码应该写得同样健壮和合理。代码应该写得对用户非常友好。这些“OT”注释不是对您的问题的回答,对代码的执行也不是强制性的,因此它们被赋予前缀“OT”(offtopic),关于:int convertor=line[i]-“0”;在尝试将第一个字符转换为int
struct node *p = malloc(...);
// next use of p:
p = other_node;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum {
maxNodes = 1000
};
struct node{
int data;
struct node* next;
};
struct node *G[maxNodes];
size_t nnode = 0;
int read_graph(const char *fn)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
fp = fopen(fn, "r");
if (fp == NULL) return -1;
while (getline(&line, &len, fp) != -1) {
char *p;
char *end;
int id;
int n;
id = strtol(line, &end, 10);
if (end == line) continue;
if (id < 1 || id > maxNodes) break;
if (id > nnode) nnode = id;
id--;
p = end;
n = strtol(p, &end, 10);
while (p != end) {
struct node *nnew = malloc(sizeof(*nnew));
nnew->data = n - 1;
nnew->next = G[id];
G[id] = nnew;
p = end;
n = strtol(p, &end, 10);
}
}
fclose(fp);
free(line);
return 0;
}
int main(void)
{
if (read_graph("test.txt") < 0) {
fprintf(stderr, "Couldn't gread raph.\n");
exit(1);
}
for (int i = 0; i < nnode; i++) {
struct node *p = G[i];
if (p) {
printf("%d:", i + 1);
for (; p; p = p->next) {
printf(" %d", p->data + 1);
}
puts("");
}
}
for (int i = 0; i < nnode; i++) {
struct node *p = G[i];
while (p) {
struct node *old = p;
p = p->next;
free(old);
}
}
return 0;
}