realloc和缓冲区溢出

时间:2012-12-05 18:03:18

标签: c

为什么result似乎无法重新分配?

  while (loc) {
    char nextLine[MAX_PATH_LEN + 30];
    sprintf(nextLine, "%s:%d\n", loc->item.pathname, loc->item.offset);
    DPRINTF('h', ("got next line\n"));
    while (spaceUsedUp + strlen(nextLine) > allocatedSize) {
      allocatedSize *= 2;
    }
    if (realloc(result, allocatedSize) == NULL) {
      perror("realloc");
    }
    DPRINTF('h', ("Next line length is %d\n", strlen(nextLine)));
    DPRINTF('h', ("Allocated size is %d\n", allocatedSize));
    DPRINTF('h', ("The size of the result is %d\n", strlen(result)));

    strcat(result, nextLine); // THIS LINE CAUSES THE BUFFER OVERFLOW                         

    spaceUsedUp += strlen(nextLine);
    DPRINTF('h', ("SpaceUsedUp is %d\n", spaceUsedUp));
    loc = loc->nextLocation;
  }

输出结果为:

got next line
Next line length is 21
Allocated size is 100
The size of the result is 0
SpaceUsedUp is 21
got next line
Next line length is 21
Allocated size is 100
The size of the result is 21
SpaceUsedUp is 42
got next line
Next line length is 21
Allocated size is 100
The size of the result is 42
SpaceUsedUp is 63
got next line
Next line length is 21
Allocated size is 100
The size of the result is 63
SpaceUsedUp is 84
got next line
Next line length is 21
Allocated size is 200
The size of the result is 84
*** buffer overflow detected ***: ./proj3/disksearch terminated

4 个答案:

答案 0 :(得分:6)

您正在丢弃realloc返回的结果。您需要将该值分配给result。典型用法如下:

if ((tmp = realloc(result, allocatedSize)) == NULL) {
      perror("realloc");
      /* more error handling here, including (usually) freeing result or exiting */
} else {
      result = tmp;
}

答案 1 :(得分:4)

realloc返回指向重新分配的缓冲区的指针,可以释放原始缓冲区。这意味着

if (realloc(result, allocatedSize) == NULL)

错误,因为它有效地丢弃了缓冲区,让您使用旧的,现在可能释放的缓冲区。你看到的问题不是缓冲区溢出;它是由于尝试写入您不再分配的内存而导致的未定义行为导致的崩溃。

您可以将代码更改为

void* tmp = realloc(result, allocatedSize);
if (tmp != NULL)
    result = tmp;
else    
    perror("realloc");

答案 2 :(得分:0)

realloc()返回类型是void *,它被转换为要求。并且此指针指向大小为allocatedSize的新内存。理想情况下,realloc可以执行四个操作,

  1. 它会创建指定大小的新内存。
  2. 将旧内存中的内容复制到更新。
  3. 释放旧记忆
  4. 返回新内存的地址

答案 3 :(得分:0)

要爱man pages,所有生命的答案都在那里......无论如何都是重要的。

  

返回值
  malloc()和calloc()函数返回一个指向已分配内存的指针,该内存适合于任何类型的变量。出错时,这些函数返回NULL。成功调用大小为零的malloc()或成功调用nmemb或大小等于零的calloc()也可以返回NULL。   free()函数不返回任何值。

     

realloc()函数返回一个指向新分配内存的指针,该内存适用于任何类型的变量,可能与ptr 不同,如果请求失败则返回NULL。如果size等于0,则返回NULL或适合传递给free()的指针。如果realloc()失败,则原始块保持不变;它没有被释放或移动。

正如您所看到的,malloc()的朋友realloc()由于突出显示的部分而在手册页中获得了唯一的条目,因此realloc()返回的值可能与引用的不同你传入的记忆。这是一个重要的记录。

所以在你的代码中:

if (realloc(result, allocatedSize) == NULL) {
  perror("realloc");
}

你无视你真正关心的结果。检查NULL是好的,但您需要分配一些临时变量然后检查。
(注意分配给临时变量的原因也在手册页中,如果realloc()失败,只要你没有覆盖它,result缓冲区仍然会很好。