重新分配与其偏移量不同的已分配内存块

Reallocate block of allocated memory different than its offset

如果我重新分配以前分配的内存区域的特定内存块,会发生什么情况?


#include <stdlib.h>

int main(void)
{
    char *area = malloc(15 + 1);

    strcpy(area, "Stack / Overflow");
    realloc(area + 5, strlen(area) + 5);

    return EXIT_SUCCESS;
}

这个例子中的area字符串会被扩展5个字节吗?

Idx: 0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21
Chr: S  t  a  c  k  [=11=] [=11=] [=11=] [=11=] [=11=]     /       O   v   e   r   f   l   o   w   [=11=]

未定义的行为。 realloc() 需要 return 由 malloc() 或家人或 NULL 指导 return。

根据 c99,第 7.20.3.4 章第 3 段,void *realloc(void *ptr, size_t size); [强调我的]

If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined. If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.


除此之外,在您的代码中

char *area = malloc(15 + 1);
strcpy(area, "Stack / Overflow");

您没有为终止 null 分配 space。结果 可能 是毁灭性的。请添加 space 以存储终止 [=17=]

另外,在使用realloc()时,请注意第二个参数。应该是 new size [intotal], not 的区别]current 分配大小。 [OP 更新的代码片段]

同样,您必须使用 realloc() 的 return 值来访问新分配的内存。旧指针 可能 不再有效。详情请阅读 man page

所以对你来说,代码应该是这样的

#include <stdlib.h>

int main(void)
{
    char *area = malloc(17);   //space for terminating null
    char * area_next = NULL;


    strcpy(area, "Stack / Overflow");   //cpy 16 chars, with null
    area_next = realloc(area, 23);                  // oldsize + 5

    return EXIT_SUCCESS;
}

分配内存块时,堆管理器会跟踪每个分配的块,以便处理连续的重新分配或释放块。 所以内存分配器非常清楚哪个内存属于它并且可以合法地调整大小或释放(通常每个分配的管理器也会构建一个隐藏的控制块,其中保存所有块属性)。 虽然标准 C99 C11 仍然假设无效指针的 未定义行为 实际上几乎所有 C 和 C++ 库实现在这种情况下都会抛出异常。