为什么这个代码在我的笔记本电脑(OSX 10.9)上运行正常,但在服务器(Linux)上运行了段错误?

时间:2013-10-31 21:57:30

标签: c linux macos gcc segmentation-fault

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

typedef char String[256];

typedef struct LinkedListNode {
String Name;
struct LinkedListNode * Next;
struct LinkedListNode * Friend;
} Node;

typedef Node * NodePointer;


NodePointer InputData(NodePointer Head) {

    String PersonName;
    NodePointer Person;
    int StringLength;
    String FormattedName;
do {    
        printf("Enter nation name :");
        fgets(PersonName,256,stdin);
        if (PersonName[0] != '\n') {
            Person = (NodePointer)malloc(sizeof(NodePointer));
            //copy all except trailing \n
            strncpy(Person->Name, PersonName, strlen(PersonName)-1);
            Person->Next = Head;
            Person->Friend = NULL;
            Head = Person;
        }
    } while (strcmp(PersonName, "\n"));
return Head;
}

void InputAllies(NodePointer Head) {
    String AllyName;
    NodePointer Ally;
    String FormattedName;
    do {    
            printf("Enter best ally for %s :", Head->Name);
            fgets(AllyName,256,stdin);  
            if (AllyName[0] != '\n') {
                Ally = (NodePointer)malloc(sizeof(NodePointer));
                //copy all except trailing \n
                strncpy(Ally->Name, AllyName, strlen(AllyName)-1);
                Head->Friend = Ally;
                Head = Head->Next;
            }
        } while (Head != NULL);
}

段错误的部分是InputAllies()函数,只有包含5个或更多元素的列表。我真的不知道发生了什么,但我认为它与我的琴弦大小有关。降低typedef字符串的大小会导致仅在3个元素之后出现段错误。

1 个答案:

答案 0 :(得分:4)

我认为在功能InputData中,在strncpy之后,您忘记将最终'\0'添加到字符串Person->Name。问题是当你打印字符串时。在你的Mac上,似乎有一个空字符碰巧在正确的地方神奇地出现;在Linux服务器上,你没那么幸运。

manual

复制
  

strcpy()函数复制src指向的字符串,   包括终止空字节('\0')到指向的缓冲区   按dest。字符串可能不重叠,并且目标字符串   dest必须足够大才能收到副本。

     

strncpy()函数类似,除了最多n个字节   src已被复制。警告:如果第一个n中没有空字节   src的字节,放在dest中的字符串不会以空值终止。

所以你的问题是最后一句话,只有当你的源字符串不能适合目标字符串的前n字节时才会发生。我认为这正是您的情况,因为您将n设置为小于源字符串的strlen。在任何情况下,您的代码中也可能存在其他错误。请使用调试器或valgrind进行检查。

BTW,我不明白为什么你想要strncpy,因为你的源和目标字符串必须具有相同的长度。为什么不使用strcpy