gpt4 book ai didi

c - "Invalid write of size 1"和指针具有正确的内存地址,但仍然会抛出错误

转载 作者:行者123 更新时间:2023-11-30 15:10:59 25 4
gpt4 key购买 nike

下面的代码给了我 2 个错误 - 大小 1 的无效写入地址 0x41f52a8 在大小为 128 的 block 分配后是 0 个字节。下面是完整的 valgrind 堆栈。

我可以进行猜测并确定 memcpy(content2 +totalLength + 1, fileContentTemp, readBytes); 代码行有问题。因此,我将其更正为 memcpy(content2 +totalLength, fileContentTemp, readBytes); 然后我的 valgrind 变得非常高兴,一切都通过了。

但我无法理解其中的原因。对我来说,从第二次开始,我需要执行 + 1 因为我不希望 memcpycontent2 + totalLength 地址开始写入因为它是写入最后一个字节的地址,所以我想增加并从下一个地址开始。

另外,另一个有趣的部分是,如果我不纠正它,我会收到以下运行时错误 *** ./server_issue' 中的错误:双重释放或损坏 (!prev): 0x08c24170 ***,我猜是因为这行代码 free(content2);free 基本上释放了指针,现在如果指针具有正确的内存地址(我验证了 content2 具有正确的内存地址)那么为什么会发生异常。

代码:

#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/jharvard/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) {
//printf("file %p\n", file);

int totalLength = 0;
int readBytes = 0;
BYTE *content2 = NULL;

BYTE *fileContentTemp[64]; // working with 222222
while ((readBytes = fread(fileContentTemp, 1, 64, file)) > 0) {
printf("Reallocating %d bytes, ", readBytes);
content2 = realloc(content2, sizeof(BYTE) * (totalLength + readBytes));

printf("%p\n", content2);
if (totalLength != 0) {
memcpy(content2 + totalLength + 1, fileContentTemp, readBytes);
} else {
memcpy(content2 + totalLength, fileContentTemp, readBytes);
}
totalLength = totalLength + readBytes;
}

*length = totalLength;
*content = content2;

free(content2);

//printf("CC image: %s\n", *content);
//printf("length is %d\n", *length);
//printf("fileContent %p\n", *content);
//printf("file %p\n", file);

fclose(file);

//printf("length is %d\n", *length);

return true;
}

Valgrind 堆栈:

appliance (~/psets/pset6/pset6_working): valgrind ./server_issue
==3206== Memcheck, a memory error detector
==3206== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3206== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3206== Command: ./server_issue
==3206==
Reallocating 64 bytes, 0x41f51b8
Reallocating 64 bytes, 0x41f5228
==3206== Invalid write of size 1
==3206== at 0x402F04B: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3206== by 0x80486AC: load (in /home/jharvard/psets/pset6/pset6_working/server_issue)
==3206== by 0x8048599: main (in /home/jharvard/psets/pset6/pset6_working/server_issue)
==3206== Address 0x41f52a8 is 0 bytes after a block of size 128 alloc'd
==3206== at 0x402C324: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3206== by 0x804865C: load (in /home/jharvard/psets/pset6/pset6_working/server_issue)
==3206== by 0x8048599: main (in /home/jharvard/psets/pset6/pset6_working/server_issue)
==3206==
Reallocating 64 bytes, 0x41f52d8
Reallocating 64 bytes, 0x41f53c8
Reallocating 60 bytes, 0x41f54f8
==3206==
==3206== HEAP SUMMARY:
==3206== in use at exit: 0 bytes in 0 blocks
==3206== total heap usage: 6 allocs, 6 frees, 1,308 bytes allocated
==3206==
==3206== All heap blocks were freed -- no leaks are possible
==3206==
==3206== For counts of detected and suppressed errors, rerun with: -v
==3206== ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 0 from 0)

最佳答案

这归结为以下事实:前 N 个整数的列表从 0 开始,到 N-1 结束。

让我们尝试一个具体的例子。假设您从索引 0 写入 4 个字节。您写入索引 0、1、2 和 3。总共 4 个字节。所以右边的下一个是索引 4,而不是 5。

假设您从索引 M 写入 N 个字节。您写入 M、M+1、...、M+N-1。你写的下一个是M+N。

因此将整个 if 语句替换为

memcpy(content2 + totalLength, fileContentTemp, readBytes); 

if 应该感觉不对。像这样的操作不需要特殊的大小写,因此您有一个 if 的事实应该引起警钟。

关于c - "Invalid write of size 1"和指针具有正确的内存地址,但仍然会抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35879470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com