【问题标题】:C - Cant free char** pointer memory - error CrtIsValidHeapPointerC - 无法释放 char** 指针内存 - 错误 CrtIsValidHeapPointer
【发布时间】:2015-10-05 16:56:53
【问题描述】:

我有一个构建字符串数组 (char*) 的函数。
使用完数组后,我想释放它的内存,但随后出现CrtIsValidHeapPointer 错误。

代码:

int main(int argc, char * argv[])
{
    char** arr = NULL;

    creating_array(&arr);    // Building the array

    //free each string memory
    for (size_t i = 0; i < 4; i++)
    {
        free(arr[i]);
    }

    // until here everything works fine :)

    //free the array memory    
    free(arr);        // Error CrtIsValidHeapPointer

    return 0;
}

void creating_array(char*** pArr)
{
    char** arr = (char**)malloc(4);
    arr[0] = (char*)malloc(5 * sizeof(char));
    strcpy(arr[0], "aaaa");
    arr[1] = (char*)malloc(5 * sizeof(char));
    strcpy(arr[1], "bbbb");
    arr[2] = (char*)malloc(5 * sizeof(char));
    strcpy(arr[2], "cccc");
    arr[3] = (char*)malloc(5 * sizeof(char));
    strcpy(arr[3], "dddd");

    *pArr = arr;
}

为什么会这样?

【问题讨论】:

  • 你没有正确分配内存。
  • 硬编码的malloc(4) 的用途是什么?
  • 你想要char** arr = malloc(4 * sizeof(char*));。另外,don't cast malloc。 @ameyCU 已修复。
  • 你说得对。问题是我认为 char** 的 4 个插槽数组的大小为 4 个字节,但正确的方法是告诉他 molloc (4 * sizeof(char**))。我可以假设 char** 指针需要保存更多信息,因此它的大小不仅仅是一个字节。 @MooseBoys

标签: c pointers memory malloc


【解决方案1】:

请尝试,在创建数组中

char **arr ;
arr=(char **) calloc( 4 , sizeof(char *));

【讨论】:

  • 谢谢,你说得对,解释是必要的。
  • calloc() 的优点是内存自动归零,可以为您省去一步。 malloc() 可以返回带有垃圾的内存。
  • 你完全正确!问题是我认为 char** 的 4 个插槽数组的大小为 4 个字节,所以我写了 molloc(4) 但正确的方法是告诉他 molloc (4 * sizeof(char**))。我可以假设 char** 指针需要保存更多信息,因此它的大小不仅仅是一个字节。谢谢你:)
【解决方案2】:

这是工作代码。它现在编译并运行。

通常在释放指针后,人们将其设置为NULL 以避免混淆(这样任何时候指针不为空,它都指向有效内存)。这样可以避免错误。此外,free(NULL) 也是合法的,因此您不会遇到双重释放地址时发生的非常严重且难以调试的问题。

重要的一点是,在这种情况下,(*pArr)[2] 中的括号很重要,它可以覆盖 C 中的运算符优先级。如果您尝试使用 *pArr[2],它假定您的意思是取消引用存储在元素 [2]。 (*pArr)[2] 表示将元素处的元素从pArr 指向的地址的位置返回。 C 假设另一种情况并且在这种情况下您需要括号的原因是另一种用法更常见,因此很方便。

注意:总是检查 malloc() 和函数调用的返回值,并制定捕获和记录错误的策略。否则,当您开始编写更大的程序时,您会发现它们极其困难、麻烦或几乎不可能调试。

另一件事是创建命名常量而不是文字,因为这样就很清楚数字是什么以及如何使用它,如果在多个地方需要该数字,则可以在一个地方进行更改。它使程序更易于阅读和理解。

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

#define STRING_COUNT 4

char **create_array(char ***pArr);

int 
main()
{
    char **arr = NULL;

    if (create_array(&arr) == NULL) {
        fprintf(stderr, "out of memory - exiting\n");
        return -1;
    }
    for (size_t i = 0; i < STRING_COUNT; i++) {
        printf("%s\n", arr[i]);
    }
    for (size_t i = 0; i < STRING_COUNT; i++) {
        free(arr[i]);
        arr[i] = NULL;
    }
    free(arr);      
    return 0;
}

char **
create_array(char ***pArr)
{
    if ((*pArr = malloc(STRING_COUNT * sizeof (char **))) == NULL) {
       return NULL;
    }
    if (((*pArr)[0] = strdup("aaaa")) == NULL) {
        return NULL;
    }
    if (((*pArr)[1] = strdup("bbbb")) == NULL) {
        free((*pArr)[0]);
        *pArr[0] = NULL;
        return NULL;
    }
    if (((*pArr)[2] = strdup("bbbb")) == NULL) {
        free((*pArr)[0]);
        *pArr[0] = NULL;
        free((*pArr)[1]);
        *pArr[1] = NULL;
        return NULL;
    }
    if (((*pArr)[3]= strdup("bbbb")) == NULL) {
        free((*pArr)[0]);
        *pArr[0] = NULL;
        free((*pArr)[2]);
        *pArr[1] = NULL;
        free((*pArr)[2]);
        *pArr[2] = NULL;
        return NULL;
    }
    return *pArr;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 2016-07-18
    • 2017-03-01
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    相关资源
    最近更新 更多