c - 内部 realloc() 的未定义行为

标签 c malloc realloc

我正在尝试编写一个 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次,它总是会给出正确的输出。然而,内部循环会随机给出正确答案,或者通过malloc:释放对象的校验和不正确错误消息退出。

我的代码库无法复制/粘贴,但以下是结构的定义:

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() 函数出错的范围,但我无法理解为什么 - 是因为我在重新分配后立即访问数组吗(但我正在更改索引,以便编辑新分配空间的数据而不是其他内容)?

我想做的是一次分配一个结构(为了节省内存),因为除非读取结构直到满足特定条件,否则没有其他方法可以知道其中有多少个结构存在。

最佳答案

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

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

请注意,您的标识符非常长,导致代码难以阅读。

iimportDescriptorArray 也存在类似的问题...

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

关于c - 内部 realloc() 的未定义行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76532365/

相关文章:

c - 在 C 中打印字符串数组的元素

c - 尝试缓冲 malloc() 分配的溢出值

const char** 和 free()

C:在没有 realloc() 的情况下调整数组大小

c - c中矩阵的重新分配

c - 循环调用realloc的缺点

arrays - 如何在 C 中打印出未知大小的字符串数组?

c - 用空结构填充 dat 文件

c - 初始化器必须是常量

c - 将 realloc() 返回的地址分配给同一个指针是好的编码习惯吗?