备注:我对“无效的下一个大小”几乎有所有的问题,但它们对我没有帮助,因为我没有malloc或realloc的另一段代码,所以这被排除了另外,我不会分配超过内存空间的限制,所以我在这方面也很好。
下面的代码给出了-*** Error in
/server_issue:realloc():无效的下一个大小:0x08249170***`。
我无法识别问题,我一次只分配64个字节,因此我没有内存地址空间不足,还有其他内存分配可能损坏了我的堆内存。
错误是说,下一个大小无效,但正如我的上一个日志告诉Reallocating 64 bytes, Aborted (core dumped)
的那样,这意味着我仍在尝试分配64个字节。那么,为什么会出错?
对于HTML文件,有任何超过256字节的文件。
代码:(再现问题的最小代码)
#include<stdio.h>
#include<stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef char BYTE;
bool load(FILE*, BYTE**, size_t*);
int main(void)
{
FILE* file = fopen("/home/university/psets/pset6/pset6_working/public/hello.html", "r");
BYTE* content;
size_t length;
load(file, &content, &length);
}
bool load(FILE* file, BYTE** content, size_t* length)
{
int totalLength = 0;
int readBytes = 0;
*content = NULL;
BYTE* fileContentTemp[64]; // working with 222222
while ((readBytes = fread(fileContentTemp, 1, 64, file)) > 0)
{
printf("Reallocating %d bytes, ", readBytes);
*content = realloc(*content, readBytes);
printf("%p\n", *content);
if(totalLength != 0)
{
memcpy(*content + totalLength + 1, fileContentTemp, readBytes);
} else{
memcpy(*content + totalLength, fileContentTemp, readBytes);
}
totalLength = totalLength + readBytes;
}
*length = totalLength;
printf("CC image: %s\n", *content);
printf("length is %d\n", *length);
printf("fileContent %p\n", *content);
return true;
}
输出:
Reallocating 64 bytes, 0x8249170
Reallocating 64 bytes, 0x8249170
*** Error in `./server_issue': realloc(): invalid next size: 0x08249170 ***
Reallocating 64 bytes, Aborted (core dumped)
更新:
即使我分配64个字节而不是在
readBytes
时使用realloc
,也会得到相同的错误。我因为这一行而出错-*content = realloc(*content, readBytes);
最佳答案
另外,我不会分配超过内存空间的限制,所以我在这方面也很好。
过分确定代码是使调试更加困难的一个好方法。怀疑一切都错了。
您没有分配足够的内存,因为您使用的realloc
不正确。p = realloc(p, n)
不会将n
字节添加到分配中,而是将总分配大小更改为您告诉它的大小。
每次通过循环传递的readBytes
是要复制的附加字节数。所以你的缓冲永远不会增长但你在文章的结尾写下:
memcpy(*content + totalLength, ...
as
totalLength
在整个循环中不断增长。在这样的循环中调用
realloc
对于性能来说通常是个坏主意你应该在前面分配足够的总空间,然后在循环中读入它。要获取总文件大小,请执行以下操作:
size_t get_file_size(FILE *f)
{
long oldpos;
size_t result;
// Save the original file position
oldpos = ftell(f);
// Seek to the first byte past the end of the file
fseek(f, 0, SEEK_END);
// Get the file position - the number of bytes in the file
result = ftell(f);
// Return the file position to where it was
fseek(f, oldpos, SEEK_SET);
return result;
}
下面是一个测试,演示我所说的
realloc
。注意,这通常使用malloc_usable_size
这是不好的做法。#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int main(void)
{
int i;
char *p = NULL;
for (i = 0; i < 10; i++) {
p = realloc(p, 16);
printf("[%d] size: %zd\n", i, malloc_usable_size(p));
}
return 0;
}
输出:
$ gcc -Wall -Werror -o realloc realloc.c
$ ./realloc
[0] size: 24
[1] size: 24
[2] size: 24
[3] size: 24
[4] size: 24
[5] size: 24
[6] size: 24
[7] size: 24
[8] size: 24
[9] size: 24
注意
malloc_usable_size()
返回相同的值,即使在多次调用传递相同大小的realloc
之后也是如此。另外,即使我们分配了16个字节,它返回24,这也是分配器实现细节的结果。从
malloc_usable_size
的手册页:笔记
由于对齐和最小大小限制,malloc_usable_size()返回的值可能大于请求的分配大小尽管应用程序可以覆盖多余的字节而不会产生不良影响,但这不是一个好的编程实践:分配中多余字节的数量取决于底层实现。
此函数主要用于调试和自省。
关于c - 重新分配内存时出现“无效的下一个大小”异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35828065/