【问题标题】:change pointer type from malloc type and free it. Does it lead to memory leak?从 malloc 类型更改指针类型并释放它。它会导致内存泄漏吗?
【发布时间】:2021-06-23 04:09:52
【问题描述】:

我使用 malloc 来分配指针类型使用的内存。然后我强行修改指针类型。使用 free func 释放内存块。我很想知道是否发生内存泄漏?

我认为 memroy 按指针类型是免费的。 "int *b" 比 "char *a" 有更广泛的内存块。我编译以下代码并运行它。没有期望发生。谁能告诉我发生了什么以及为什么?

#include <stdlib.h>

int
main(int argc, char **argv) {
        char *a = (char*)malloc(sizeof(char));
        int *b = (int*)a;
        free(b);
}

【问题讨论】:

  • 不,它不会改变任何东西。 free 没有“看到”指针的类型,它只看到一个指针。
  • C++ new/delete 的答案会很不一样。

标签: c++ c memory malloc free


【解决方案1】:

malloc 系列中的例程跟踪它们保留的所有内存,包括大小。当您将地址传递给free 时,例程会在其记录中查找该地址并释放为其分配的空间量。

free 只传递了一个地址。它没有关于调用者用作参数的指针类型的信息。因为 free 被声明为 void free(void *),所以传递给它的任何指针都会自动转换为 void *,并且 free 只接收 void *,而不接收来自 int * 或其他类型的任何信息。

【讨论】:

    【解决方案2】:

    为了说明一些其他人已经说过的内容,请尝试执行以下程序:

    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    int main(int argc, char** argv) {
        char* b = (char*)malloc(0x01020304);
        strcpy(b, "ABCDEFG");
        for (int index = -16; index < 16; index++) {
            printf("%02x ", (unsigned char) *(b + index));
        }
        free(b);
        return 0;
    }
    

    程序的输出(基本上是缓冲区位置周围内存的十六进制转储):

    01 00 00 00 04 03 02 01 4e 00 00 00 fd fd fd fd 41 42 43 44 45 46 47 00 cd cd cd cd cd cd cd cd
    

    您可以看到缓冲区的内容(41 42 43 44 45 46 47 是十六进制的 ABCDEFG)。所以,在这个例子中,“b”只是指向内存中的那个位置,但在那之前还有更多的东西。就在内容之前有四个“fd”字节(与问题无关,但很有趣)。这是一个“栅栏”,用于检查您的程序是否写入缓冲区边界之外。例如,如果您执行 *(b - 1) = 'A' 之类的操作,内存管理器会在释放块时检测到这一点,因为它会看到栅栏已被修改。在缓冲区的末尾有一个类似的栅栏(比这个更可能被覆盖)。

    但除此之外,您还可以在此之前看到缓冲区本身的长度(04 03 02 01)。您必须考虑到 intel 对数据使用 little-endian 表示法,因此内存中的大小与我们人类的预期相反。

    因此,当您在缓冲区上调用 free 时,内存管理器只是从您作为参数传递的位置向后移动并计算它必须释放的缓冲区的大小。指针的类型并不重要。

    我在 Visual Studio 2019 中执行了此操作并进行了调试,因此如果您在另一个平台上自己尝试,您的里程可能会有所不同(您甚至可能无法找到块大小,因为该信息可能存储在内存中的其他位置以及什么您之前的缓冲区是指向该信息的指针),但基本思想是相同的:内存管理器存储有关您正在分配的块的大量信息,例如块大小,因此指针的类型您在免费中使用并不重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-26
      • 2021-06-14
      • 2013-11-14
      相关资源
      最近更新 更多