Hello? I'm studying Doubly Linked List
Anyway, when I used to put data on node, there were C6011 error [:Dereferencing Null Pointer 'NewNode']
So I refered https://docs.microsoft.com/ko-kr/visualstudio/code-quality/c6011?view=vs-2019 and
tried to check null value. But It didn't work..
I checked some details on error window like picture I added
They said 'NewNode will be NULL', 'NewNode will be still NULL even if it is dereferenced'
Code is like below
1.header file(DoubleLinkedList.h)
#pragma once
#ifndef DOUBLY_LINKEDLIST_H
#define DOUBLY_LINKEDLIST_H
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int ElementType;
typedef struct MyNode
{
ElementType Data;
struct MyNode* Prev;
struct MyNode* Next;
}Node;
Node* DLL_CreateNode(ElementType NewData); //1.create node
void DLL_DestroyNode(Node* Node);//2.destroy node
void DLL_AppendNode(Node** Head, Node* NewNode);//3.append node
/*
4.insert node
connect
prev-insert-next
*/
void DLL_InsertAfter(Node* Current, Node* NewNode);
void DLL_RemoveNode(Node** Head, Node* Remove);//5.remove node
Node* DLL_GetNodeAt(Node* Head, int location);//6.search node
int DLL_GetNodeCount(Node* Head);//7.count the number of nodes
#endif
2.DLL.cpp(which is for header file)
#include "DoubleLinkedList.h"
Node* DLL_CreateNode(ElementType NewData)
{
//create node with memory allocation
Node* NewNode = (Node*)malloc(sizeof(Node));
//nullptr check for c6011(https://docs.microsoft.com/ko-kr/visualstudio/code-quality/c6011?)
if (NewNode)
{
NewNode->Data = NewData;
NewNode->Prev = NULL;
NewNode->Next = NULL;
}
return NewNode;
}
void DLL_DestroyNode(Node* Node)
{
free(Node);
}
void DLL_AppendNode(Node** Head, Node* NewNode)
{
if ((*Head) == NULL)
{
*Head = NewNode;
}
else
{
Node* Tail = (*Head);
while (Tail->Next != NULL)
{
Tail = Tail->Next;
}
Tail->Next = NewNode;
NewNode->Prev = Tail;
}
}
void DLL_InsertAfter(Node* Current, Node* NewNode)
{
NewNode->Prev = Current->Next;
NewNode->Next = Current;
if (Current->Next != NULL)
{
Current->Next->Prev = NewNode;
Current->Next = NewNode;
}
}
void DLL_RemoveNode(Node** Head, Node* Remove)
{
if (*Head == Remove)
{
*Head = Remove->Next;
if (*Head != NULL)
{
(*Head)->Prev = NULL;
}
Remove->Next = NULL;
Remove->Prev = NULL;
}
else
{
Node* Temp = Remove;
if (Remove->Prev != NULL)
{
Remove->Prev->Next = Temp->Next;
}
if (Remove->Next != NULL)
{
Remove->Next->Prev = Temp->Prev;
}
Remove->Prev = NULL;
Remove->Next = NULL;
}
}
Node* DLL_GetNodeAt(Node* Head, int location)
{
Node* Current = Head;
while (Current != NULL && (--location) >= 0)
{
//--location >=0 is for check index
Current = Current->Next;
}
return Current;
}
int DLL_GetNodeCount(Node* Head)
{
int count = 0;
Node* Current = Head;
while (Current != NULL)
{
Current = Current->Next;
count++;
}
return count;
}
3.Practice file(.c)
#include "DoubleLinkedList.h"
int main()
{
int i = 0;
int Count = 0;
Node* List = NULL;
Node* Current = NULL;
Node* NewNode = NULL;
//create&append nodes
for (i = 0; i < 5; i++) {
NewNode = DLL_CreateNode(i);
DLL_AppendNode(&List, NewNode);
}
Count = DLL_GetNodeCount(List);
for (i = 0; i < Count; i++) {
Current = DLL_GetNodeAt(List, i);
printf("List[%d] : %d\n", i, Current->Data);
}
Current = DLL_GetNodeAt(List, 2);
NewNode = DLL_CreateNode(3000);
DLL_InsertAfter(Current, NewNode);
Count = DLL_GetNodeCount(List);
for (i = 0; i < Count; i++) {
Current = DLL_GetNodeAt(List, i);
printf("List[%d] : %d\n", i, Current->Data);
}
for (i = 0; i < Count; i++) {
Current = DLL_GetNodeAt(List, 0);
if (Current != NULL) {
DLL_RemoveNode(&List, Current);
DLL_DestroyNode(Current);
}
}
return 0;
}
Thank you!
These is a warning from the static analyzer. The compiler says that there might be something potentially wrong.
And indeed, in DLL_CreateNode there is a call to malloc that could fail and return a NULL. You check it inside the function, which is fine.
But if malloc fails, you would still return a NULL to the caller in main.c.
NewNode = DLL_CreateNode(i); //<-- this could return NULL
DLL_AppendNode(&List, NewNode);
In this case, this NULL would be given to DLL_AppendNode as the second parameter.
If there is an existing head node at this point in time, then in DLL_AppendNode at this line:
NewNode->Prev = Tail;
it would give an EXC_BAD_ACCESS exception.
The static analyzer has thus correctly identified a potential problem.
There are several ways to deal with it. One solution would be to check for NULL, print an error message on stderr, and exit the program with an error code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With