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

时间:2015-01-13 11:56:02

标签: c memory-management realloc

如果我重新分配以前分配的内存区域的特定内存块会怎样?


#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  \0 \0 \0 \0 \0     /       O   v   e   r   f   l   o   w   \0

2 个答案:

答案 0 :(得分:5)

未定义的行为。 realloc()需要malloc()或家人或NULL返回的指针。

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

  

如果ptr是空指针,则realloc函数的行为类似于malloc函数   指定大小。否则,如果ptr与先前返回的指针不匹配   calloc,malloc或realloc函数,或者如果空间已被呼叫解除分配   对于free或realloc函数,行为未定义。如果记忆为新的   无法分配对象,旧对象未被释放,其值不变。


除此之外,在您的代码中

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

你没有分配空间来终止null。结果可能是毁灭性的。请为存储终止\0添加空间。

此外,在使用realloc()时,请注意第二个参数。它应该是大小[总计], 当前分配大小的差异。 [由OP更新的代码段]

同样,您必须使用realloc()的返回值来访问新分配的内存。旧指针可能不再有效。有关详细信息,请阅读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;
}

答案 1 :(得分:0)

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