释放char *数据不起作用

时间:2018-04-06 15:19:01

标签: c pointers char malloc free

我有一个List,列表中的每个节点都包含一个char *数据字段,该字段必须与节点本身进行malloc,但是当我尝试释放该数据时,控制台只是停止,它不会崩溃,他们没有错误,没有。但是,如果我将其注释掉并且只释放列表节点,那么它可以正常工作。

我这样做了吗?

void removeSpecificData(List *list, char *course)
{
    ListNodePtr currentNode = list->head;
    ListNodePtr previousNode = NULL;

    while (currentNode != NULL)
    {
        if (strcmp(currentNode->data, course) == 0)
        {
            ListNodePtr nodeToFree = currentNode;

            if (previousNode == NULL)
            {
                list->head = currentNode->nextNode;
                currentNode = list->head;
            }
            else
            {
                previousNode->nextNode = currentNode->nextNode;
                currentNode = previousNode->nextNode;
            }

            printf("Free Data");
            free(nodeToFree->data);
            printf("Free Node");
            free(nodeToFree);
        }
        else
        {
            previousNode = currentNode;
            currentNode = currentNode->nextNode;
        }
    }
}

这是我的createListNode函数,因此需要查看。

ListNodePtr createListNode(char *newCourse)
{
    ListNodePtr newNode = (ListNodePtr)malloc(sizeof(struct ListNode));
    newNode->data = (char *)malloc(sizeof(strlen(newCourse) + 1));
    strcpy(newNode->data, newCourse);
    newNode->nextNode = NULL;

    return newNode;
}

提前致谢。

3 个答案:

答案 0 :(得分:3)

以下行不正确。

newNode->data = (char *)malloc(sizeof(strlen(newCourse) + 1));

sizeof()部分不对。如果字符串的长度大于sizeof(size_t),则最终会分配比您需要的内存更少的内存。跟随它的strcpy调用将使用超出您分配的内存。因此,您的程序将具有未定义的行为。

使用

newNode->data = malloc(strlen(newCourse) + 1);

请参阅Do I cast the result of malloc?

答案 1 :(得分:2)

分配大小不正确。只有在尝试释放内存(损坏的内存列表)时,系统才会检测到它。

为什么不呢:

newNode->data = strdup(newCourse);

它将分配适当的大小(与您的尝试不同)并同时复制字符串(不需要mallocstrcpy

答案 2 :(得分:0)

对于初学者来说,函数removeSpecificData至少有一个拼写错误或错误,因为没有变量nodeToFree的声明,并且没有赋值给变量。

所以这句话

free(nodeToFree);

没有意义。

同样在这个else块中,第二个表达式语句没有意义。

    else
    {
        previousNode->nextNode = currentNode->nextNode;
        currentNode = previousNode->nextNode;
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    }

功能太复杂了。它可以写得更简单。例如

void removeSpecificData(List *list, const char *course)
{
    ListNodePtr *currentNode = &list->head;

    while ( *currentNode != NULL && strcmp( ( *currentNode )->data, course) != 0 )
    {
        currentNode = &( *currentNode )->nextNode;
    }

    if ( *currentNode != NULL )
    {
        ListNodePtr tmp = *currentNode;
        *currentNode = ( *currentNode )->nextNode;

        free( tmp->data );
        free( tmp );
    }
}    

关于函数createListNode,然后是表达式

strlen(newCourse) + 1

的类型为size_t。所以表达式的值没有被评估:)

sizeof(strlen(newCourse) + 1)

等同于表达式

sizeof( size_t )

并且等于4或8,具体取决于类型size_t的定义。

你只想写

newNode->data = (char *)malloc( strlen(newCourse) + 1 );