realloc和缓冲区溢出

realloc和缓冲区溢出,c,C,为什么结果似乎没有得到重新分配 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) {

为什么
结果
似乎没有得到重新分配

  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

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

if ((tmp = realloc(result, allocatedSize)) == NULL) {
      perror("realloc");
      /* more error handling here, including (usually) freeing result or exiting */
} else {
      result = tmp;
}
返回指向重新分配的缓冲区的指针,可以释放原始缓冲区。这意味着

if (realloc(result, allocatedSize) == NULL)
是错误的,因为它实际上丢弃了缓冲区,让您使用旧的、现在可能已释放的缓冲区。您看到的问题不是缓冲区溢出本身;相反,它是由于试图写入不再分配的内存而导致的未定义行为导致的崩溃

您可以将代码更改为

void* tmp = realloc(result, allocatedSize);
if (tmp != NULL)
    result = tmp;
else    
    perror("realloc");
realloc()返回类型为void*,它是根据需求铸造的。这个指针指向大小为allocatedSize的新内存。理想情况下,realloc执行四个操作

  • 它创建指定大小的新内存
  • 将内容从旧内存复制到新内存
  • 释放旧的记忆
  • 返回新内存的地址
  • 我要爱你,生活的答案都在那里。。。不管怎样,重要的是

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

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

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

    因此,在您的代码中:

    if (realloc(result, allocatedSize) == NULL) {
      perror("realloc");
    }
    
    你忽视了你真正关心的结果。检查
    NULL
    很好,但您需要分配一些临时变量,然后进行检查。

    (注意,分配给临时变量的原因也在手册页中,如果
    realloc()
    失败,则
    结果
    缓冲区仍将正常,只要您不覆盖它)

    如果realloc错误,这是内存泄漏,由于result的原始值现在已丢失。@williampersell我认为我提议的更改没有问题。您在哪里看到内存泄漏?或者您的意思是OP的代码泄漏了重新分配的缓冲区?这与以下问题相同:
    result=malloc(…);结果=空
    。如果realloc出错,您需要跟踪
    结果中的旧值。(虽然通常会退出
    或免费)哎呀,我明白你的意思了。谢谢,现在修好了。