Don2Quixote Asked:2020-01-04 10:23:11 +0000 UTC2020-01-04 10:23:11 +0000 UTC 2020-01-04 10:23:11 +0000 UTC 内存会被移位的指针释放吗? 772 char *data = malloc(5); data++; free(data); 程序将如何处理这样的代码?内存会从新地址中释放出来,还是什么都不会释放? c 2 个回答 Voted Best Answer Anton Menshov 2020-01-04T10:34:05Z2020-01-04T10:34:05Z 这样的使用free()会导致未定义的行为。 根据一篇关于 cppreference 的文章(俄语自动翻译): 如果 ptr 的值不等于 、 、 或 (自 C11 起)先前返回的值,malloc()则calloc()行为realloc()未定义aligned_alloc()。 这实际上将是您提供的代码的结果。data执行后的价值 data++; 变得不等于之前返回的 char *data = malloc(5); 因此,您可以期待任何事情,由不同编译器编译的不同平台上的相同代码可能会有不同的行为。事实上你绝对不应该这样做:),并且让你的代码依赖于未定义的行为是一条通往痛苦的道路。 你很有可能会得到以下结果: *** Error in `XXX' free(): invalid pointer: 0x0000000000YYYYYY *** 但是,当然,不能保证。 Zergatul 2020-01-04T11:36:21Z2020-01-04T11:36:21Z 简单来说,函数free必须从某个地方知道要释放多少内存。它只接收一个指针作为输入,这意味着,根据这个指针,函数计算需要释放多少内存。必要的信息保存在某处malloc。具体在哪里以及如何取决于实施,该标准没有给出任何指示。当您增加指针时,它会free错误地计算要释放的内存量。内部内存管理器的函数将被调用,并且很可能程序会崩溃。让我提醒您,通常malloc/free他们不会请求也不会将内存还给操作系统。在操作系统中以大块的形式请求内存,然后才malloc从其中为程序提供必要的片段。 例如,我在 Microsoft C++ 编译器/环境中运行以下代码: void testmalloc(int size) { char *data = malloc(size); data -= 8; int* x = data; printf("%d\n", *x); } int main() { testmalloc(16); testmalloc(64); testmalloc(256); testmalloc(1024); testmalloc(4096); } 结论: 71 73 74 75 76 如您所见,环境在相对于地址的 -8 字节偏移处记住了一些 4 字节的索引。如果将指针向前移动 1 个字节,则该函数free将得到一些垃圾而不是所需的索引。
这样的使用
free()会导致未定义的行为。根据一篇关于 cppreference 的文章(俄语自动翻译):
这实际上将是您提供的代码的结果。
data执行后的价值变得不等于之前返回的
因此,您可以期待任何事情,由不同编译器编译的不同平台上的相同代码可能会有不同的行为。事实上你绝对不应该这样做:),并且让你的代码依赖于未定义的行为是一条通往痛苦的道路。
你很有可能会得到以下结果:
但是,当然,不能保证。
简单来说,函数
free必须从某个地方知道要释放多少内存。它只接收一个指针作为输入,这意味着,根据这个指针,函数计算需要释放多少内存。必要的信息保存在某处malloc。具体在哪里以及如何取决于实施,该标准没有给出任何指示。当您增加指针时,它会free错误地计算要释放的内存量。内部内存管理器的函数将被调用,并且很可能程序会崩溃。让我提醒您,通常malloc/free他们不会请求也不会将内存还给操作系统。在操作系统中以大块的形式请求内存,然后才malloc从其中为程序提供必要的片段。例如,我在 Microsoft C++ 编译器/环境中运行以下代码:
结论:
如您所见,环境在相对于地址的 -8 字节偏移处记住了一些 4 字节的索引。如果将指针向前移动 1 个字节,则该函数
free将得到一些垃圾而不是所需的索引。