visual studio 未分配的指针不是 NULL

visual studio unallocted pointer not NULL

我在 Visual Studio 中遇到了一个让我抓狂的问题。 它是关于未分配的指针。

我想写一个简单的链表app.The问题是释放和未分配的指针不是 NULL,这阻止了我迭代列表。

考虑以下 C 代码

#include "stdafx.h"
#include <malloc.h> 

typedef struct _item
{
    char data;
    struct _item * pNext;
}item, *pItem;

int _tmain(int argc, _TCHAR* argv[])
{
    pItem listHead;
    pItem listTemp;
    pItem listCurr;

    listHead = (pItem) malloc(sizeof(listHead));
    listHead->data = '0';
    listHead->pNext = NULL; //will create exception in free

    listTemp = listHead;

    while(listTemp->pNext != NULL) //issue 1
    {
        listTemp = listTemp->pNext;//0xfdfdfdfd - never NULL? how to check?
    }

    listCurr = (pItem) malloc(sizeof(listHead));
    listCurr->data = '1';
    listCurr->pNext = NULL; //will create exception in free
    listTemp->pNext = listCurr;

    listTemp = listHead;
    while(listTemp->pNext != NULL)  //issue 2
    {
        printf("%d ", listTemp->data - 48); //"0 "
        listTemp = listTemp->pNext;
    }

    printf("%d ", listTemp->data - 48);
    free(listTemp); //is set to oxfeeefee not to NULL?  //issue 3


    listTemp = listHead;
    while(listTemp->pNext != NULL)  //issue 4
    {
        listTemp = listTemp->pNext;
    }

    free(listTemp);//Not null?

    return 0;
}

在问题 1 和问题 2 中,listTemp->pNext 不是 NULL,而是 0xfdfdfdfd。这可以防止获取列表中的最后一个元素 在第 3 行中,free 没有将释放的指针设置为 null,而是设置为 0xfeeefeee。这使我无法再次获取最后一个元素。

我该如何处理这些问题? 感谢您的帮助。

您这里似乎有一些问题。您遇到的一个问题是您没有分配足够的内存。

listHead = (pItem) malloc(sizeof(listHead));

listHead 是一个指针。所以你只分配足够的内存来保存一个指针,而不是保存整个 item 结构。应该是:

listHead = (pItem) malloc(sizeof(item));

我不明白问题 1 第一次怎么可能不为 NULL。您是否使用调试器逐步完成?然而,没有分配足够内存的问题肯定会导致 free() 的问题,而且很难确定它可能会导致什么其他问题。

语法略有改动以适合我的编译器。如前所述,两个主要问题是 (1) 没有分配足够的内存。 (2) 解析列表的顺序错误。

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

typedef struct item {
    char data;
    struct item * pNext;
} item, *pItem;

void show (pItem list, int cue) {
    printf("List %d: ", cue);
    while(list != NULL) {
        printf("%c ", list->data); 
        list = list->pNext;
    }
    printf("\n");
}

int main(int argc, char* argv[]) {
    pItem listHead, listTemp, listCurr;

    listHead = malloc(sizeof(item));
    listHead->data = '0';
    listHead->pNext = NULL;
    show(listHead, 1);

    listCurr = malloc(sizeof(item));
    listCurr->data = '1';
    listCurr->pNext = NULL;
    listHead->pNext = listCurr;
    show(listHead, 2);

    printf("Freeing: "); 
    while(listHead != NULL) {
        listTemp = listHead;
        printf("%c ", listHead->data); 
        listHead = listHead->pNext;
        free(listTemp);
    }
    printf("\n");

    show(listHead, 3);
    return 0;
}

上面的代码遵循了您将下一项添加到列表尾部的方法,但我通常会将其添加到头部之前并设置一个新的 listHead.

listCurr = malloc(sizeof(item));
listCurr->data = '1';
listCurr->pNext = listHead;
listHead = listCurr;

这也适用于 第一个 项,前提是您初始化 listHead = NULL 以指示空列表。

答案是您必须自己将指向已释放内存的指针设置为NULL。 free函数只会将指针处的内存释放回堆。指针参数是按值传递的,不能被free函数本身修改。

此外,您还需要保留对列表中前一项的引用,这样当您释放内存并将指针设置为 NULL 时,您是在列表项中而不是在临时指针中执行此操作.

listCurr = NULL;
listTemp = listHead;

while(listTemp->pNext != NULL)
{
    listCurr = listTemp;
    listTemp = listTemp->pNext;
}

if(NULL != listCurr)
{
    free(listCurr->pNext);
    listCurr->pNext = NULL;
}