5

为什么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

4 回答 4

6

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

if ((tmp = realloc(result, allocatedSize)) == NULL) {
      perror("realloc");
      /* more error handling here, including (usually) freeing result or exiting */
} else {
      result = tmp;
}
于 2012-12-05T18:05:06.797 回答
4

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

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

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

您可以将代码更改为

void* tmp = realloc(result, allocatedSize);
if (tmp != NULL)
    result = tmp;
else    
    perror("realloc");
于 2012-12-05T18:05:30.810 回答
0

realloc() 返回类型为 void*,它被强制转换为需求。并且这个指针指向大小为allocatedSize 的新内存。理想情况下 realloc 做四个操作,

  1. 它创建指定大小的新内存。
  2. 将旧内存中的内容复制到新内存。
  3. 释放旧记忆
  4. 返回新内存的地址
于 2012-12-05T18:18:59.590 回答
0

一定要喜欢手册页,所有生命的答案都在那里……无论如何,重要的答案。

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

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

正如您所看到的,由于突出显示的部分,malloc()朋友在手册页中获得了唯一的条目,从返回的值可能与您传入的对内存的引用不同。这是一个重要的注意事项。realloc()realloc()

所以在你的代码中:

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

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

于 2012-12-05T18:30:19.163 回答