C语言 链表-分段错误



这段代码应该生成一个由用户输入的十个名字组成的链接列表它应该会打印出这个列表。

#include<stdio.h>
#include<stdlib.h>
struct NameList
{
    char *name;
    struct NameList *nname;
};
typedef struct NameList NL;
int main()
{
    int i;
    NL *first;
    NL *next;
    first = (NL*)malloc(sizeof(NL));
    if (first ==NULL)
            printf("Memory not properly allocatedn");
    NL *pNames;
    pNames =  first;
    for(i = 0; i<10; i++)
    {
            printf("Enter a name: ");
            scanf("%s", &pNames->name);
            if(i == 9)
                    next = NULL;
            else
                    next = (NL*)malloc(sizeof(NL));
            pNames->nname = next;
            pNames = pNames->nname;
    }

到这里还没有问题,我输入了十个名字,但一旦我输入我得到一个分割错误的姓氏。我猜它起源于这里,但我一点也不确定

        pNames = first;
        while(pNames != NULL)
        {
                printf("%sn", pNames->name);
                pNames = pNames->nname;
        }

    }

这一行是源代码:

printf("Enter a name: ");
scanf("%s", &pNames->name);
最好像这样创建一个静态缓冲区:
char buf[20];
然后

printf("Enter a name: ");
scanf("%s", buf);
最后

:

pNames->name = strdup(buf);

Edit:为了完整起见,存在缓冲区溢出的风险。超过一定数量的字符超出缓冲区的末尾,导致未定义的行为。这可以通过@ebyrob来缓解,以这种方式

fgets(buf, 20, stdin);
allocate space for "name", preferably use std::string
    you need to get "next" node.
      for(i = 0; i<10; i++)
            {
                    printf("Enter a name: ");
                    scanf("%s", &pNames->name);
                    if(i == 9)
                            next = NULL;
                    else
                            next = (NL*)malloc(sizeof(NL));
                    pNames->nname = next;
                    pNames = next;
            }
              pNames = first;
                while(pNames != NULL)
                {
                        printf("%sn", pNames->name);
                        pNames = pNames->next;
                }

您没有分配内存来保存NameList对象的name字段。name字段的类型是char *,它有足够的空间容纳一个指针,而不是一个字符串。当您执行scanf(%s, &pNames->name);时,您告诉scanf将名称写入该内存位置,但这将覆盖比存储指针所需的字节更多的字节。

您可以先将scanf加载到一个临时数组中,然后再将malloc加载到足够的空间中

char *tempbuff = malloc(128); // or some large enough buffer
for (i = 0; i<10; ++i) {
    // load the input into tempbuff first
    scanf("%s", tempbuff);
    // now make room for the string in the current object
    pNames->name = malloc(strlen(tempbuff)+1); // leave room for trailing null
    // now copy it from the tempbuff to its new home
    strcpy(pNames->name,tempbuff);
    .... // rest of code

最新更新