1

Я пытался создать связанный список, используя «Объектно-ориентированный» C. Но я не знаю, как отменить ошибку сегментации, поэтому I не может найти решение.Ошибка сегментации - Объектно-ориентированный C - Связанный список

Библиотека, вы знаете ...

#include <stdio.h> 
#include <stdlib.h> 

В структуре у меня есть два указателя на функцию. Эти указатели имитируют методы (что-то вроде этого).

struct nodeList { 
    int data; 
    struct nodeList * nextPtr; 
    void (*print)(struct nodeList *); 
    void (*insert)(struct nodeList **, int); 
    int (*delete)(struct nodeList **, int); 
}; 

Вы знаете, я ненавижу писать -структуру каждый раз.

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->insert(&myList, 3); 

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

myList->print(myList); 

    free(myList); 
    return 0; 
} 

функции объявления, вы знаете. INIT это, как я уже сказал, что-то вроде конструктор. Он возвращает экземпляр NodeListPtr с указательными функциями, указывающими на r est функций.

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, поэтому я не знаю, как это исправить.

+1

Вы можете запустить свою программу на gdb, а затем попросить просмотреть трассировку стека при ее сбое. http://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_42.html – danielfranca

+0

, когда вы вынуждаете C быть чем-то, что его нет, оно имеет тенденцию к обратным атакам на вас .. –

+7

0) 'NodeListPtr instance = (NodeListPtr) malloc (sizeof (NodeListPtr)); '->' NodeListPtr instance = (NodeListPtr) malloc (sizeof (NodeList)); ' – BLUEPIXY

ответ

2

Заменить

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

с

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

в коде

- BLUEPIXY

0

Поскольку ваша ошибка сегментации происходит внутри функции вставки можно предположить, что один виноват ,

Проблема, кажется, в этом коде (на самом деле не создала код ...но правила C компилятор позволил оценить выражение в любом порядке)

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; 
    } 
} 

предполагающей, что было ваше намерение, не проверьте логику позади этого на самом деле, но дело в том, что иначе вы разыскиваете нулевой указатель там, потому что, хотя вы делаете проверку, чтобы компилятор мог ее оценивать в любом порядке, который он выбирает ... поэтому взломать его на некоторое время и a, если это делает так, чтобы ваш код был безопасным с derefe обрезая нулевой указатель.

+1

Вы уверены? Я думал, что оценка короткого замыкания означает, что сначала ему нужно было оценить левую сторону, чтобы она не оценивала правую сторону, если левая сторона была достаточной. https://en.wikipedia.org/wiki/Short-circuit_evaluation –

+0

Вы правы, извините! – xception

Смежные вопросы