我正在try 编写一个PE解析器,我的程序包含两个循环,如下所示:

    size_t i = 0;
    while (condition_1) {
        struct _IMAGE_IMPORT_DESCRIPTOR64 *importDescriptorArray = malloc(sizeof(struct _IMAGE_IMPORT_DESCRIPTOR64));

        struct _IMAGE_THUNK_DATA64 *originalFirstThunkArray = malloc(sizeof(struct _IMAGE_THUNK_DATA64));

        size_t originalFirstThunkArrayIndex = 0;

        originalFirstThunkArray[originalFirstThunkArrayIndex].u1.ordinal = some_value; //set to a computed value

        while (condition_2) {
            originalFirstThunkArrayIndex++;

            originalFirstThunkArray = realloc(originalFirstThunkArray, originalFirstThunkArrayIndex * sizeof(struct _IMAGE_THUNK_DATA64));

            originalFirstThunkArrayOffset += sizeof(QWORD); //each element has its address stored as a QWORD, so I have to iterate QWORD-at-a-time.
            originalFirstThunkArray[originalFirstThunkArrayIndex].u1.ordinal = reverse_endianess_u_int64_t(readQWord(file, originalFirstThunkArrayOffset, QWORD_Buffer));
        }

        i++;
        importDescriptorArray = realloc(importDescriptorArray, i * sizeof(struct _IMAGE_IMPORT_DESCRIPTOR64));
    }

我可以执行外部循环n次,它总是会给我正确的输出.然而,inner循环会随机给出正确答案,或者通过malloc: Incorrect checksum for freed object错误消息退出.

我的代码库超出了复制/粘贴的范围,但以下是 struct 的定义:

struct _IMAGE_IMPORT_DESCRIPTOR64 {
    union {
        DWORD Characteristics;
        IMAGE_THUNK_DATA32 OriginalFirstThunk;
    } u;
    DWORD timeDateStamp;
    DWORD forwarderChain;
    DWORD name;
    IMAGE_THUNK_DATA32 FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR64;

typedef struct _IMAGE_THUNK_DATA64 {
    union {
        QWORD forwarderString;
        QWORD function;
        QWORD ordinal;
        QWORD addressOfData;
    } u1;
} IMAGE_THUNK_DATA64;

我已经将导致错误的行缩小到内部循环的realloc()函数,但我不能理解原因-是因为我在重新分配之后立即访问数组(但我更改了索引,以便编辑新分配的空间的数据,而不是其他内容)?

我try 做的是一次分配一个 struct (为了节省内存),因为除非在满足特定条件之前读取这些 struct ,否则没有其他方法可以知道它们有多少.

推荐答案

originalFirstThunkArrayIndex是数组最后一个元素的索引,而不是数组的长度.您应该在循环中使用一个额外的元素重新分配:

    originalFirstThunkArray = realloc(originalFirstThunkArray,
                                      (originalFirstThunkArrayIndex + 1) *
                                      sizeof(struct _IMAGE_THUNK_DATA64));

请注意,您的标识符非常长,这使得代码很难阅读.

iimportDescriptorArray也有类似的问题...

最后,还有一个更重要的问题:importDescriptorArray是在外部while循环体中本地定义的,因此它的值在每次迭代时都会丢失.

C++相关问答推荐

修改pGM使用指针填充2-D数组但不起作用

Mise()在虚拟内存中做什么?

C中的__attributor__((aligned(4),packed))与 struct 的用法

创建一个fork导致fget无限地重新读取文件

fwrite无法写入满(非常大)缓冲区

为什么我从CSV文件中进行排序和搜索的代码没有显示数据的所有结果?

如何使用_newindex数组我总是得到错误的参数

C将数组传递给函数以修改数组

OSDev--双缓冲重启系统

int * 指向int的哪个字节?

与外部SPI闪存通信时是否应禁用中断?

即使我在C++中空闲,也肯定会丢失内存

将复合文字数组用作临时字符串缓冲区是否合理?

RISC-V GCC编译器错误编译ASM代码

分支预测和UB(未定义的行为)

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

std::malloc/calloc/realloc/free 与纯 C 的 malloc/calloc/realloc/free 有什么不同

如何使用 VLA 语法使用 const 指针声明函数

比 * 更快的乘法

我们可以在不违反标准的情况下向标准函数声明添加属性吗?