0

我很难弄清楚我的程序出了什么问题。我正在尝试通过在 createNode 函数中创建节点然后使用 addNode 将它们添加到列表的头部来创建链接列表。当我尝试创建节点时程序失败并且出现分段错误。

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

struct listnode {
    int line;
   char *word;
   struct lnode *next;
};


struct listnode* createNode (char* word, int line) {
  int strlen1 = strlen(word)+1;
    struct lnode *node = malloc(sizeof(struct lnode));
    node->word = malloc(sizeof(char)*strlen1);
    strcpy(node->word,word);
    node->word[strlen1] = '\0';
    node->next = NULL;
    node->line = line;
    return node;
}


void addNode (struct listnode** head, struct listnode* node) {
    if ((*head)==NULL){
    head = &node;
    }
    else if((*head)->next!=NULL){
        struct lnode *temp = *head;
        node->next = *head;
    }else if(*head!=NULL&&(*head)->next==NULL){
        (*head->next) = node;
    }
    }

通过 valgrind 运行程序会产生以下错误:

==14661== Command: ./testlist
==14661== 
==14661== Invalid write of size 1
==14661==    at 0x4006E3: createNode (in /u/data/u95/testprogs/testlist)
==14661==    by 0x40091C: main (in /u/data/u95/testprogs/testlist)
==14661==  Address 0x51dc0a6 is 0 bytes after a block of size 6 alloc'd
==14661==    at 0x4C2AF5D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64  linux.so)
==14661==    by 0x4006AF: createNode (in /u/data/u95/testprogs/testlist)
==14661==    by 0x40091C: main (in /u/data/u95/testprogs/testlist)
==14661== 
==14661== Use of uninitialised value of size 8
==14661==    at 0x40071C: addNode (in /u/data/u95/testprogs/testlist)
==14661==    by 0x400933: main (in /u/data/u95/testprogs/testlist)
==14661==  Uninitialised value was created by a stack allocation
==14661==    at 0x4008E8: main (in /u/data/u95/testprogs/testlist)
==14661== 
==14661== Invalid read of size 8
==14661==    at 0x40071C: addNode (in /u/data/u95/testprogs/testlist)
==14661==    by 0x400933: main (in /u/data/u95/testprogs/testlist)
==14661==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==14661== 
==14661== 
==14661== Process terminating with default action of signal 11 (SIGSEGV)
==14661==  Access not within mapped region at address 0x0
==14661==    at 0x40071C: addNode (in /u/data/u95/testprogs/testlist)
==14661==    by 0x400933: main (in /u/data/u95/testprogs/testlist)
==14661==  If you believe this happened as a result of a stack
==14661==  overflow in your program's main thread (unlikely but
==14661==  possible), you can try to increase the size of the
==14661==  main thread stack using the --main-stacksize= flag.
==14661==  The main thread stack size used in this run was 8388608.

我是 C 新手,我不确定为什么会抛出这些错误。有人可以帮忙吗?

4

2 回答 2

1

我找不到 的定义lnode。是一样的listnode吗?

addNode 错误地设置了头部元素并且没有正确找到长列表的尾部。它应该是这样的

void addNode(struct listnode** head, struct listnode* node) {
    if ((*head)==NULL){
        *head = node;
    }
    else {
        struct listnode* tail = *head;
        while (tail->next != NULL) {
            tail = tail->next;
        }
        tail->next = node;
    }
}

您缺少*head一个空列表的分配。设置的值head改变了本地指针而不是调用者的指针。对于更长的列表,您需要遍历所有成员以找到尾部。

这可能会解决您的Use of uninitialised value of size 8错误。如果没有,您需要向我们展示调用addNode.

createNode可以简化wordto的分配/初始化

node->word = malloc(strlen(word)+1);
strcpy(node->word,word);

您不需要设置空终止符 -strcpy将为您复制它。而且,正如 William Pursell 所指出的,这实际上是一个重要的变化,因为它避免了你在字符串末尾之外的书写。这将解决您的Invalid write of size 1错误。

于 2013-02-16T19:35:38.197 回答
1

以下保证是错误的:

node->word = malloc(sizeof(char)*strlen1);
...
node->word[strlen1] = '\0';

您为 word 分配 strlen1 个字节,因此您可能的意思是:

node->word[strlen1 - 1] = '\0';

请注意,您甚至不需要写入空字节,因为strcpy它会为您完成。目前尚不清楚代码中还有哪些其他错误,并且在您修复此错误之前不值得一看。

于 2013-02-16T19:42:15.083 回答