C、获取分段错误
C, Getting segmentation fault
我有一个名为 islands.txt 的文件,其内容为:
islandone
islandtwo
islandthree
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct island{
char *name;
struct island *previous;
} island;
void printIsland(island is){
printf("%s", is.name);
if(is.previous && is.previous->name[0] != '[=11=]'){
printf("%s", is.previous->name);
}
}
int main(){
// the file to be read.
FILE *islandsFile = fopen("islands.txt","r");
// temporary location to store the name read from the file.
char name[40];
// temporary pointer to an island which has been already read for linking.
island *previousIsland;
while(fscanf(islandsFile,"%s",name) != EOF){
// allocate space for a new island and point to it with (*newIsland) pointer
island *newIsland =malloc(sizeof(island));
// assign name
newIsland->name = name;
// if previousIsland pointer is not null
// it means there is an island that was read before newIsland in the file
if(previousIsland){
// newIsland.previous should hold the address of this previously read island..
newIsland->previous = previousIsland;
}
// now previousIsland is the newIsland..
previousIsland = newIsland;
printIsland(*newIsland);
puts("");
}
fclose(islandsFile);
}
我对输出的期望是:
islandone
islandtwoislandone
islandthreeislandtwo
相反,我得到的只是分段错误。我已经尝试了一切,但我被困住了。我在哪里得到分段错误?我是 C 的新手,我不知道如何调试。
是的,您还需要为名称分配内存。你只分配结构
typedef struct island{
char *name;
struct island *previous;
} island;
所以这个
// assign name
newIsland->name = name;
将指针设置为您在堆栈上的数组,但在每次循环迭代中,它将是相同的地址。
而是做类似
的事情
newIsland->name = strdup(name);
或者如果您愿意
newIsland->name = malloc( strlen( name ) + 1 );
strcpy( newIsland->name, name );
这里有几个问题。除了 CyberSpock 提到的那些之外,您还有以下代码:
island *previousIsland;
while(fscanf(islandsFile,"%s",name) != EOF){
/* some code omitted */
if(previousIsland){
newIsland->previous = previousIsland;
}
previousIsland变量未初始化,if第一次可能为真,导致previous指针指向无效内存。然后当你到达 printIsland 的末尾时,它将继续跟随未初始化的指针,到达无效内存。我还看到您没有 free() 任何内存,但这可能是因为您不关心这么小的例子。
要调试 C 程序,调试器是你的朋友。现在你不知道你使用哪个 OS 和编译器,但如果你使用 gcc,gdb 是匹配的调试器。
我有一个名为 islands.txt 的文件,其内容为:
islandone
islandtwo
islandthree
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct island{
char *name;
struct island *previous;
} island;
void printIsland(island is){
printf("%s", is.name);
if(is.previous && is.previous->name[0] != '[=11=]'){
printf("%s", is.previous->name);
}
}
int main(){
// the file to be read.
FILE *islandsFile = fopen("islands.txt","r");
// temporary location to store the name read from the file.
char name[40];
// temporary pointer to an island which has been already read for linking.
island *previousIsland;
while(fscanf(islandsFile,"%s",name) != EOF){
// allocate space for a new island and point to it with (*newIsland) pointer
island *newIsland =malloc(sizeof(island));
// assign name
newIsland->name = name;
// if previousIsland pointer is not null
// it means there is an island that was read before newIsland in the file
if(previousIsland){
// newIsland.previous should hold the address of this previously read island..
newIsland->previous = previousIsland;
}
// now previousIsland is the newIsland..
previousIsland = newIsland;
printIsland(*newIsland);
puts("");
}
fclose(islandsFile);
}
我对输出的期望是:
islandone
islandtwoislandone
islandthreeislandtwo
相反,我得到的只是分段错误。我已经尝试了一切,但我被困住了。我在哪里得到分段错误?我是 C 的新手,我不知道如何调试。
是的,您还需要为名称分配内存。你只分配结构
typedef struct island{
char *name;
struct island *previous;
} island;
所以这个
// assign name
newIsland->name = name;
将指针设置为您在堆栈上的数组,但在每次循环迭代中,它将是相同的地址。
而是做类似
的事情newIsland->name = strdup(name);
或者如果您愿意
newIsland->name = malloc( strlen( name ) + 1 );
strcpy( newIsland->name, name );
这里有几个问题。除了 CyberSpock 提到的那些之外,您还有以下代码:
island *previousIsland;
while(fscanf(islandsFile,"%s",name) != EOF){
/* some code omitted */
if(previousIsland){
newIsland->previous = previousIsland;
}
previousIsland变量未初始化,if第一次可能为真,导致previous指针指向无效内存。然后当你到达 printIsland 的末尾时,它将继续跟随未初始化的指针,到达无效内存。我还看到您没有 free() 任何内存,但这可能是因为您不关心这么小的例子。
要调试 C 程序,调试器是你的朋友。现在你不知道你使用哪个 OS 和编译器,但如果你使用 gcc,gdb 是匹配的调试器。