Can';t在C语言中将一个节点附加到我的链表的末尾

Can';t在C语言中将一个节点附加到我的链表的末尾,c,data-structures,linked-list,C,Data Structures,Linked List,我创建了一个链表,可以在每个节点上存储一个字符串和一个int。我可以在列表的顶部添加节点,也可以删除它们,但在列表的末尾添加节点时会遇到一些麻烦 我当前的函数append会将节点设置在列表的末尾,但是在我追加一个节点并尝试追加另一个节点后,我会得到分段错误,就好像程序无法在已经有另一个节点的情况下追加新的last,我目前正在尝试调试它,但找不到出现错误的确切行 // self-referential structure struct listNode

我创建了一个链表,可以在每个节点上存储一个字符串和一个int。我可以在列表的顶部添加节点,也可以删除它们,但在列表的末尾添加节点时会遇到一些麻烦

我当前的函数
append
会将节点设置在列表的末尾,但是在我追加一个节点并尝试追加另一个节点后,我会得到
分段错误
,就好像程序无法在已经有另一个节点的情况下追加新的
last
,我目前正在尝试调试它,但找不到出现错误的确切行

// self-referential structure                       
struct listNode {                                      
   char *data; // each listNode contains a character
   int num;
   struct listNode *nextPtr; // pointer to next node
}; 


typedef struct listNode ListNode; // synonym for struct listNode
typedef ListNode *ListNodePtr; // synonym for ListNode*

void append(ListNodePtr *sPtr, char *value, int valore)
 {  /* 1. allocate node */

    ListNodePtr lastNode = malloc(sizeof(ListNode)+1);

    ListNode *last = *sPtr; 

    /* 2. put in the data  */
    last->data= malloc(strlen(value));
    strcpy(last->data, value);
    last->num = valore;

    /* 3. This new node is going to be the last node, so make next 
          of it as NULL*/
    lastNode->nextPtr = NULL;

    /* 4. If the Linked List is empty, then make the new node as head */
    if (*sPtr == NULL)
    {
       *sPtr = lastNode;
       return;
    }  

    /* 5. Else traverse till the last node */
    while (last->nextPtr != NULL)
        last = last->nextPtr;

    /* 6. Change the next of last node */
    last->nextPtr = lastNode;

 }

// insert a new value into the list in sorted order
void insert(ListNodePtr *sPtr, char *value, int valore)
{ 
   ListNodePtr newPtr = malloc(sizeof(ListNode)+1); // create node

   if (newPtr != NULL) { // is space available
      newPtr->data= malloc(strlen(value));
      strcpy(newPtr->data, value);
      newPtr->num = valore;
      newPtr->nextPtr = NULL; // node does not link to another node
      ListNodePtr previousPtr = NULL;
      ListNodePtr currentPtr = *sPtr;
      // loop to find the correct location in the list       
      while (currentPtr != NULL && value > currentPtr->data) {
         previousPtr = currentPtr; // walk to ...               
         currentPtr = currentPtr->nextPtr; // ... next node 
      }                                          
      // insert new node at beginning of list
      if (previousPtr == NULL) { 
         newPtr->nextPtr = *sPtr;
         *sPtr = newPtr;
      } 
      else { // insert new node between previousPtr and currentPtr
         previousPtr->nextPtr = newPtr;
         newPtr->nextPtr = currentPtr;
      } 
   } 
   else {
      printf("%s not inserted. No memory available.\n", value);
   } 
}

你这里有很多错误。不确定问题的原因,但请尝试解决此问题:

如果不一致,为什么要使用同义词

ListNodePtr lastNode = malloc(sizeof(ListNode)+1);

ListNode *last = *sPtr; 
为什么是+1

ListNodePtr lastNode = malloc(sizeof(ListNode)+1)
这:

覆盖发送到此方法的节点的值。可能打算使用lastNode

现在你需要+1

last->data= malloc(strlen(value));

这就是我现在看到的,不知道它是否能修复分割错误。这个错误是如何发生的?你只使用这种方法吗?还是你在对数据进行各种各样的操作?也许问题出在别的地方。无论如何,我会再看一眼,看看我是否发现了其他东西。

永远不要
typedef
a(数据)指针。这会混淆代码,不会保存任何键入(事实上,您必须键入更多),而且一旦您使用增强的C功能(如
const
correction),它会使事情变得更加复杂(一旦您对C有点熟练,您会注意到)我用来研究的那本书报告了很多使用typedef的数据结构的例子,这真是太疯狂了,应该更清楚我没有说不要
typedef
a
struct
。但我同意,外面有很多蹩脚的书。其中许多是为K&R C编写的,K&R C没有提供
const
,其他限定词如
volatile
通常不在裸机软件之外使用。然而,正如我用更多的知识写的那样,你应该能够弄清楚这种不当行为的问题是什么——除了模糊之外。在此之前:最好是显式的而不是隐式的。这里有一个问题:“newPtr->data=malloc(strlen(value));”它只短一个字符(NUL terminator)。定义指针的类型没有那么糟糕,只要它是明显的,例如'ListNodePtr'或'pListNode'(当然,使用正确:)。我会发布整个程序,但它确实很长。无论如何,谢谢你的帮助:)
last->data= malloc(strlen(value));