为什么这段代码在我的笔记本电脑(OSX 10.9)上运行良好,而在服务器(Linux)上运行segfault? #包括 #包括 #包括 typedef字符字符串[256]; typedef结构LinkedListNode{ 字符串名; 结构LinkedListNode*下一步; 结构LinkedListNode*朋友; }节点; typedef节点*NodePointer; 节点间输入数据(节点间头){ 字符串PersonName; 人际关系; 整数字符串长度; 字符串格式化名称; 做{ printf(“输入国家名称:”); fgets(人名,256,标准输入); 如果(PersonName[0]!='\n'){ Person=(NodePointer)malloc(sizeof(NodePointer)); //复制除尾部以外的所有内容\n strncpy(Person->Name,PersonName,strlen(PersonName)-1); 人->下一个=头; Person->Friend=NULL; 头=人; } }而(strcmp(PersonName,“\n”)); 回流头; } 无效输入(节点接口头){ 字符串AllyName; 结交; 字符串格式化名称; 做{ printf(“输入%s的最佳盟友:”,Head->Name); fgets(AllyName,256,标准名称); 如果(AllyName[0]!='\n'){ Ally=(NodePointer)malloc(sizeof(NodePointer)); //复制除尾部以外的所有内容\n strncpy(Ally->Name,AllyName,strlen(AllyName)-1); 头->朋友=盟友; 头部=头部->下一步; } }while(Head!=NULL); }

为什么这段代码在我的笔记本电脑(OSX 10.9)上运行良好,而在服务器(Linux)上运行segfault? #包括 #包括 #包括 typedef字符字符串[256]; typedef结构LinkedListNode{ 字符串名; 结构LinkedListNode*下一步; 结构LinkedListNode*朋友; }节点; typedef节点*NodePointer; 节点间输入数据(节点间头){ 字符串PersonName; 人际关系; 整数字符串长度; 字符串格式化名称; 做{ printf(“输入国家名称:”); fgets(人名,256,标准输入); 如果(PersonName[0]!='\n'){ Person=(NodePointer)malloc(sizeof(NodePointer)); //复制除尾部以外的所有内容\n strncpy(Person->Name,PersonName,strlen(PersonName)-1); 人->下一个=头; Person->Friend=NULL; 头=人; } }而(strcmp(PersonName,“\n”)); 回流头; } 无效输入(节点接口头){ 字符串AllyName; 结交; 字符串格式化名称; 做{ printf(“输入%s的最佳盟友:”,Head->Name); fgets(AllyName,256,标准名称); 如果(AllyName[0]!='\n'){ Ally=(NodePointer)malloc(sizeof(NodePointer)); //复制除尾部以外的所有内容\n strncpy(Ally->Name,AllyName,strlen(AllyName)-1); 头->朋友=盟友; 头部=头部->下一步; } }while(Head!=NULL); },c,linux,macos,gcc,segmentation-fault,C,Linux,Macos,Gcc,Segmentation Fault,segfaults的具体部分是InputAllies()函数,并且只包含5个或更多元素的列表。我真的不知道发生了什么,但我想这与我的弦的大小有关。降低typedef字符串的大小只会在3个元素之后导致segfault 我认为在函数InputData中,就在strncpy之后,您忘记了将最后的'\0'添加到字符串Person->Name。问题在于打印字符串时。在你的Mac电脑上,似乎有一个空字符恰好神奇地出现在正确的位置;在Linux服务器上,您没有那么幸运 从以下位置复制: strcpy()函数复

segfaults的具体部分是InputAllies()函数,并且只包含5个或更多元素的列表。我真的不知道发生了什么,但我想这与我的弦的大小有关。降低typedef字符串的大小只会在3个元素之后导致segfault

我认为在函数
InputData
中,就在
strncpy
之后,您忘记了将最后的
'\0'
添加到字符串
Person->Name
。问题在于打印字符串时。在你的Mac电脑上,似乎有一个空字符恰好神奇地出现在正确的位置;在Linux服务器上,您没有那么幸运

从以下位置复制:

strcpy()
函数复制由
src
指向的字符串, 将终止的空字节(
'\0'
)包含到指向的缓冲区 通过
dest
。字符串不能重叠,目标字符串不能重叠 dest必须足够大以接收副本

strncpy()
src
被复制。警告:如果第一个
n
如果是
src
的字节,则放置在
dest
中的字符串将不会以null结尾

因此,您的问题是最后一句话,只有当源字符串无法放入目标字符串的第一个
n
字节时,才会出现问题。我认为这正是您的情况,因为您正在将
n
设置为小于源字符串的
strlen
。在任何情况下,代码中也可能存在其他错误。使用调试器或valgrind进行检查


顺便说一句,我不明白你为什么要
strncpy
在那里,因为你的源字符串和目标字符串必须具有相同的长度。为什么不使用strcpy呢?

我认为在函数
InputData
中,就在
strncpy
之后,您忘记了将最后的
'\0'
添加到字符串
Person->Name
。问题在于打印字符串时。在你的Mac电脑上,似乎有一个空字符恰好神奇地出现在正确的位置;在Linux服务器上,您没有那么幸运

从以下位置复制:

strcpy()
函数复制由
src
指向的字符串, 将终止的空字节(
'\0'
)包含到指向的缓冲区 通过
dest
。字符串不能重叠,目标字符串不能重叠 dest必须足够大以接收副本

strncpy()
src
被复制。警告:如果第一个
n
如果是
src
的字节,则放置在
dest
中的字符串将不会以null结尾

因此,您的问题是最后一句话,只有当源字符串无法放入目标字符串的第一个
n
字节时,才会出现问题。我认为这正是您的情况,因为您正在将
n
设置为小于源字符串的
strlen
。在任何情况下,代码中也可能存在其他错误。使用调试器或valgrind进行检查


顺便说一句,我不明白你为什么要
strncpy
在那里,因为你的源字符串和目标字符串必须具有相同的长度。为什么不改用strcpy呢?

valgrind告诉过你什么吗?请发布堆栈跟踪。你对strncpy的使用不正确,
strncpy
并不总是空终止。@ouah同意。当您尝试strlcpy(Person->name,PeronName,256)
时会发生什么?另外,请用宏替换sentinel
256
值,如
#define BUF_LENGTH(256)
。Valgrind多次抱怨大小为8的无效写入和读取地址不是堆栈d malloc'd或free'd。Valgrind告诉您什么了吗?请发布堆栈跟踪。您使用的
strncpy
是不正确的,
strncpy
并不总是空终止。@ouah同意。当您尝试strlcpy(Person->name,PeronName,256)
时会发生什么?另外,请用宏替换sentinel
256
值,如
#define BUF_LENGTH(256)
。Valgrind多次抱怨大小为8的地址写入和读取无效,而不是堆栈d malloc'd或free'd。如果src字符串长度小于dest字符串长度,则实际为null终止结果。
#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);
}