Исключение, выданное при 0x011414CE в chars.exe : 0xC0000005: Местоположение чтения 0x00000004 с нарушением доступа

#c #pointers #memory #doubly-linked-list

#c #указатели #память #двусвязный список

Вопрос:

Итак, я создаю код для программы с использованием C, который просто выполняет основные задачи связанного списка, такие как создание списка, вставка узла после заданного текущего узла, удаление узла и т.д.

Я использую visual studio 2015, поэтому, когда я попытался протестировать свою функцию вставки после узла, отладив ее и используя visual studio watch для визуализации моего списка и того, правильно ли он вставлял узлы после текущего узла, я получил сообщение об ошибке:

Исключение, выданное при 0x011414CE в chars.exe : 0xC0000005: местоположение чтения 0x00000004 с нарушением доступа.

Необработанное исключение при 0x011414CE в chars.exe : 0xC0000005: местоположение чтения 0x00000004 с нарушением доступа.

Итак, вот мой файл .h с объявлением структуры и списка

 #ifndef DLIST_H
#define DLIST_H


typedef struct DListNode_struct {
char *str;
int blankIndex;
int blankLength;
struct DListNode_struct *next;
struct DListNode_struct *prev;
} DListNode;

typedef struct DList_struct {
   int size;
   DListNode *head;
   DListNode *tail;
} DList;


void DListConstruct(DList* list);

void DListInsertAfter(DList* list, DListNode* currNode, DListNode* newNode);

#endif // DLIST_H
  

итак, вот моя основная функция

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

int main() {

DList* list = NULL;
DListNode* currNode = NULL;

DListNode* newNode1 = (DListNode*)malloc(sizeof(DListNode));

DListInsertAfter(list, currNode, newNode1);



return 0;
}
  

И вот мой файл .c, в котором у меня есть функция insertafter

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


void DListConstruct(DList* list) {

list->head = NULL;
list->tail = NULL;
list->size = 0;

}



void DListInsertAfter(DList* list, DListNode* currNode, DListNode* newNode) {

DListNode* sucNode;

if (list->head == NULL) {
    list->head = newNode;
    list->tail = newNode;
}

else if (currNode == list->tail) {
    list->tail->next = newNode;
    newNode->prev = list->tail;
    list->tail = newNode;
}

else {
    sucNode = currNode->next;
    newNode->next = sucNode;
    newNode->prev = currNode;
    currNode->next = newNode;
    sucNode->prev = newNode;
}
}
  

Я нашел несколько сообщений, связанных с моим вопросом, но все они либо не нацелены на связанные списки, либо не находятся в C.

Итак, кто-нибудь может помочь мне найти, где ошибка?

Заранее спасибо.

Комментарии:

1. Отладчик должен точно указать вам, какая строка кода вызывает ошибку seg. Пожалуйста, укажите это как минимум. Стоит потратить время, чтобы научиться более эффективно использовать отладчик.

Ответ №1:

Вы переходите NULL к DListInsertAfter as list , и первая проверка (list->head == NULL) завершается неудачей при доступе к нулевому указателю.

Ответ №2:

Dlist after получает список, который равен НУЛЮ, поэтому list->head проблема заключается в том, что происходит. Поскольку оно не существует!

Сначала вам нужно выделить список.

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

int main() {

DList* list = NULL;
DListNode* currNode = NULL;

DListNode* newNode1 = (DListNode*)malloc(sizeof(DListNode));

DList* list = (void*)malloc(sizeof(DList));

DListInsertAfter(list, currNode, newNode1);



return 0;
}
  

Комментарии:

1. Я думаю, вы пытались выделить жирным шрифтом строку кода в Markdown; вы не можете этого сделать, так что теперь похоже, что вы немного довольны звездочками, хаха…

2. Упс, я спешил ответить на его вопрос, но, похоже, некоторые другие люди ответили раньше, чем я: D

Ответ №3:

оператор стрелки -> является синтаксическим сахаром для разыменования в сочетании с доступом к элементу структуры. Поэтому строка

 if (list->head == NULL) {
  

совпадает с

 if ((*list).head == NULL) {
  

При вызове DListInsertAfter() вы передаете указатель на list параметр, который инициализируется NULL . Поэтому вы разыменовываете NULL указатель, что, вероятно, вызывает сбой. В какой-то момент вам нужно выделить память для вашей DList структуры, прежде чем пытаться получить к ней доступ.