分段故障面向对象C链表

分段故障面向对象C链表,c,pointers,data-structures,linked-list,singly-linked-list,C,Pointers,Data Structures,Linked List,Singly Linked List,我试图用«面向对象»C制作一个链表。 但我不知道如何回溯分割错误,所以我 无法找到解决方案 图书馆,你知道 #include <stdio.h> #include <stdlib.h> 你知道,我讨厌每次都写struct typedef struct nodeList NodeList; typedef NodeList * NodeListPtr; 原型声明。init有点像构造函数。我不需要析构函数,函数free()处理这个问题 NodeListPtr init(i

我试图用«面向对象»C制作一个链表。 但我不知道如何回溯分割错误,所以我 无法找到解决方案

图书馆,你知道

#include <stdio.h>
#include <stdlib.h>
你知道,我讨厌每次都写struct

typedef struct nodeList NodeList;
typedef NodeList * NodeListPtr;
原型声明。init有点像构造函数。我不需要析构函数,函数free()处理这个问题

NodeListPtr init(int);
void print(NodeListPtr);
void insert(NodeListPtr *, int);
int delete(NodeListPtr *, int);

int main(void)
{
  NodeListPtr myList = init(0);

  myList->insert(&myList, 5);
以下是分段错误发生的地方:(

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  myList->print(myList);

  free(myList);
  return 0;
}
函数声明,你知道。 正如我所说,init类似于构造函数,它返回一个NodeListPtr实例,指针函数指向其余函数

NodeListPtr init(int data)
{
  NodeListPtr instance = (NodeListPtr) malloc(sizeof(NodeListPtr));
  instance->data = data;
  instance->nextPtr = NULL;
  instance->print = &print;
  instance->insert = &insert;
  instance->delete = &delete;

  return instance;
}
迭代列表并打印所有数据

void print(NodeListPtr listPtr)
{
  NodeListPtr currentPtr = listPtr;

  while(currentPtr != NULL) {
    printf("%d -> ", currentPtr->data);
    currentPtr = currentPtr->nextPtr;
  }

  puts("(NULL)");
}
以有序的方式插入元素

void insert(NodeListPtr *selfPtr, int value)
{
  NodeListPtr newPtr;
  NodeListPtr previousPtr;
  NodeListPtr currentPtr;

  newPtr = init(value);

  if(newPtr != NULL) {
    previousPtr = NULL;
    currentPtr = *selfPtr;

    while(currentPtr != NULL && value > currentPtr->data) {
      previousPtr = currentPtr;
      currentPtr = currentPtr->nextPtr;
    }

    if(previousPtr == NULL) {
      newPtr->nextPtr = *selfPtr;
      *selfPtr = newPtr;
    } else {
      previousPtr->nextPtr = newPtr;
      newPtr->nextPtr = currentPtr;
    }
  } else {
    printf("Could not add %d. No memory available\n", value);
  }
}
删除列表中的一个元素。如果该元素不存在,则返回空字符

int delete(NodeListPtr *selfPtr, int data)
{
  NodeListPtr tempPtr;
  NodeListPtr currentPtr;
  NodeListPtr previousPtr;

  if((*selfPtr)->data == data) {
    tempPtr = *selfPtr;
    *selfPtr = (*selfPtr)->nextPtr;
    free(tempPtr);

    return data;
  } else {
    previousPtr = *selfPtr;
    currentPtr = (*selfPtr)->nextPtr;

    while(currentPtr != NULL && currentPtr->data != data) {
      previousPtr = currentPtr;
      currentPtr = currentPtr->nextPtr;
    }

    if(currentPtr != NULL) {
      tempPtr = currentPtr;
      previousPtr->nextPtr = currentPtr->nextPtr;
      free(tempPtr);

      return data;
    }
  }

  return '\0';
}
就是这样。就像我说的,我不知道如何用GDB对分段错误进行回溯,所以我不知道如何修复它。

替换

NodeListPtr instance = (NodeListPtr) malloc(sizeof(NodeListPtr));

在代码中


–BLUEPIXY

由于您的分段错误发生在insert函数内部,因此我们可以认为是一个原因造成的

问题似乎出在这段代码中(实际上并没有生成代码……但根据C规则,编译器可以按任意顺序计算表达式)

您的代码应该改为按

while(currentPtr != NULL) {
    if(currentPtr->data != data) {
        previousPtr = currentPtr;
        currentPtr = currentPtr->nextPtr;
    } else {
        break;
    }
}

假设这是您的意图,实际上并没有检查它背后的逻辑,但问题是,否则您将取消对空指针的引用,因为尽管您是按顺序进行检查的,但编译器可以按照其选择的任何顺序对其进行计算……因此,将其分为一段时间和一个if,这样您的代码就不会取消对空指针的引用空指针。

您可以在gdb上运行程序,然后在程序崩溃时要求查看堆栈跟踪。当您强制C成为非C的对象时,它往往会适得其反..0)
NodeListPtr instance=(NodeListPtr)malloc(sizeof(NodeListPtr))-->
NodeListPtr实例=(NodeListPtr)malloc(sizeof(NodeList))你确定吗?我认为短路评估意味着它必须先评估左侧,这样如果左侧足够,它就不会评估右侧。
NodeListPtr instance = (NodeListPtr) malloc(sizeof(NodeListPtr));
NodeListPtr instance = (NodeListPtr) malloc(sizeof(NodeList));
while(currentPtr != NULL && currentPtr->data != data) {
  previousPtr = currentPtr;
  currentPtr = currentPtr->nextPtr;
}
while(currentPtr != NULL) {
    if(currentPtr->data != data) {
        previousPtr = currentPtr;
        currentPtr = currentPtr->nextPtr;
    } else {
        break;
    }
}