简体   繁体   English

链表-细分错误

[英]Linked List - Segmentation Fault

This code is supposed to make a link list of ten names inputed by the user and it should print out that list. 该代码应构成用户输入的十个名称的链接列表,并应打印出该列表。

#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 allocated\n");
    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;
    }

Up to here there are no issues, I input the ten names but as soon as I enter the last name I get a segmentation fault. 到这里为止,没有问题,我输入了十个名称,但是一旦输入姓氏,就会出现分割错误。 I'm guessing it's originating from here but I am not sure at all 我猜它起源于此,但我不确定

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


    }

This line is the source: 该行是源:

printf("Enter a name: ");
scanf("%s", &pNames->name);

Would be best to create a static buffer like this: 最好创建一个像这样的静态缓冲区:

char buf[20];

then 然后

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

finally: 最后:

pNames->name = strdup(buf);

Edit: For sake of completeness, there is a risk of buffer overflow. 编辑:为了完整起见,存在缓冲区溢出的风险。 where more than certain characters go past the end of the buffer inducing undefined behaviour. 其中超过某些字符的字符超过了缓冲区的末尾,从而导致未定义的行为。 This can be mitigated as suggested by @ebyrob , in this fashion @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("%s\n", pNames->name);
                        pNames = pNames->next;
                }

You have not allocated memory to hold the name field of your NameList objects. 您尚未分配内存来保存NameList对象的name字段。 The name field is of type char * which has enough room for a pointer, not a string of characters. name字段的类型为char * ,它有足够的空间容纳指针,而不是字符串。 When you perform scanf(%s, &pNames->name); 当您执行scanf(%s, &pNames->name); you are telling scanf to write the name into that memory location, but that will overwrite a lot more than the bytes needed to store a pointer. 您告诉scanf将名称写入该内存位置,但这将覆盖比存储指针所需的字节更多的东西。

Instead you could have scanf load into a temporary array first, then malloc enough space to hold it 相反,您可以先将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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM