【问题标题】:Another dynamic memory allocation bug另一个动态内存分配错误
【发布时间】:2011-02-26 21:53:15
【问题描述】:

我正在尝试为多维数组(8 行 3 列)分配内存。

这是分配的代码(我相信你很清楚错误)

char **ptr = (char **) malloc( sizeof(char) * 8);

for (i = 0; i < 3; i++)
    ptr[i] = (char *) malloc( sizeof(char) * 3);

当我引用这个时发生崩溃:

ptr[3][0];

在 0x0135144d 处未处理的异常 xxxx.exe: 0xC0000005:访问冲突写入 位置 0xabababbab。

对于这类主题有推荐的参考资料/阅读资料吗?

谢谢。

【问题讨论】:

    标签: c pointers malloc dynamic-memory-allocation


    【解决方案1】:

    第一个malloc() 是错误的。应该是:

    malloc(sizeof(char*) * 8)
    

    char* 是 4 字节(或 8 字节...见附注),而 char 是 1 字节。当您编写ptr[3] 时,编译器将假定您要访问ptr + 3*sizeof(char*) 的基地址。因此,您将访问未分配的内存。

    附注:

    更准确地说,char* 在 32 位系统上是 4 字节,在 64 位系统上是 8 字节。

    【讨论】:

      【解决方案2】:

      您的代码中有几个错误/不一致,但第一个主要错误是第一次分配中的错误sizeof。如果您遵循一些良好的实践指南,您所犯的错误很容易避免:

      (1) 尽可能避免在语句中使用类型名称。类型名称属于声明,而不是语句。

      (2)不要强制转换内存分配函数的结果。

      第一次分配应该如下所示

      char **ptr = malloc( 8 * sizeof *ptr );
      

      试着记住这是一个通用模式:malloc 请求通常应该如下所示

      pointer = malloc( count * sizeof *pointer );
      

      注意:以上声明中没有提到类型名称。

      当然,您还应该确定 2D 数组的第一个大小。您尝试分配 8,然后您只初始化 3。为什么?

      【讨论】:

      • 不幸的是,C++ 要求您进行强制转换,因此如果您想编写对两者都有效的代码,则需要强制转换。
      • @Matthew Flaschen:是的,但是这个问题被标记为 C。此外,“编写对两者都有效的代码”的问题通常仅适用于头文件。除非您在头文件中编写内联函数或宏,否则大小写(或不强制转换)malloc 通常不会出现与 C++ 兼容性有关的问题。
      【解决方案3】:
      char **ptr = (char **) malloc( sizeof(char *) * 8);
      

      以前,您为 8 个字符分配空间。您需要 8 个指向 char 的指针的空间。

      Michael 指出了另一个错误,即从您从未分配的字符串中写入第一个字符。

      如果您使用常量可能会有所帮助,例如:

      const int STRING_COUNT = 8;
      const int STRING_LEN = 2;
      
      char **ptr = (char **) malloc( sizeof(char *) * STRING_COUNT);
      

      【讨论】:

        【解决方案4】:

        ptr是8个指针的数组,不是chars,所以第一行应该是:

        char **ptr = (char **) malloc( sizeof(char*) * 8)
        

        因为有 8 个指针,所以循环应该是从 0 到 7:

        for (i = 0; i < 8; i++)
        

        您也可以考虑使用不易出错的第一行版本:

        char **ptr = (char **) malloc( sizeof(*ptr) * 8)
        

        最后一个:

        ptr[i] = (char *) malloc( sizeof(*ptr[i]) * 3);
        

        规则是:总是取sizeof 的解引用左值。如果左值是ptr,那么你需要sizeof(*ptr)ptr[i] 变为 sizeof(*ptr[i])

        【讨论】:

          【解决方案5】:

          有两个问题。

          首先,正如其他人指出的那样,您的初始 malloc 应该是

          malloc(sizeof(char *) * 8)

          其次,您正在初始化 8 元素数组中的前 三个 元素,但 ptr[3][0] 指的是 第四 元素。因此崩溃。

          【讨论】:

            【解决方案6】:

            我不知道任何关于内存分配的书,但是任何介绍性的 C 教程都应该解释它。至于您的错误,您的 for 循环仅初始化前 3 行,而不是您分配的 8 行。应该是:

            for (i = 0; i < 8; i++)
            

            【讨论】:

            • @m4design other answers 也是对的;有两个错误,我没有注意到malloc 一个,所以请务必修复两个错误
            猜你喜欢
            • 1970-01-01
            • 2020-01-14
            • 2021-08-23
            • 2011-02-17
            • 1970-01-01
            • 2016-05-14
            • 2019-04-26
            相关资源
            最近更新 更多