You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态分配int64_t数组realloc后输出异常/双释放错误排查

问题分析与代码错误修复

代码中的核心错误

你的array_resize函数存在三个致命问题,直接导致了不同场景下的异常:

1. realloc内存大小计算错误

realloc的第二个参数应该是新数组的总大小乘以元素字节数,但你错误地用增量resize_num来计算:

int64_t *temp = realloc(*array, sizeof(int64_t) * resize_num);

正确的计算应该基于new_size(原大小+增量):

int64_t *temp = realloc(*array, sizeof(int64_t) * new_size);

这个错误会让实际分配的内存远小于需要的总大小,后续访问超出分配范围的元素时,就会出现乱码这类未定义行为。

2. 错误释放刚分配的内存

在把*array指向temp后,你立刻执行了free(temp):

*array = temp;
free(temp);

此时temp和*array指向同一块内存,free(temp)会直接释放掉刚调整好的数组内存,后续对array的操作都是在访问已释放的内存(野指针),这会导致数据错乱或内存错误。

3. 内存错误处理逻辑错误

当realloc失败时,你错误地释放了二级指针array:

free(array);

array是传入的指针的地址(二级指针),真正需要释放的是原来的数组内存*array;而且更合理的是,realloc失败时不会修改原指针,所以不需要在这里释放原内存,应该让调用者决定后续处理,避免丢失原数据。

修正后的代码

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>

size_t array_resize(int64_t **array, size_t array_size, size_t resize_num) {
    size_t new_size = array_size + resize_num;
    // 修正:使用new_size计算内存总大小
    int64_t *temp = realloc(*array, sizeof(int64_t) * new_size);
    if (temp == NULL) {
        fprintf(stderr, "failed realloc\n");
        // realloc失败时原内存未被修改,直接退出即可
        exit(EXIT_FAILURE);
    }
    *array = temp;
    // 移除错误的free(temp)调用
    return new_size;
}

int main(void) {
    int array_size = 10;
    int64_t *array;
    array = malloc(array_size * sizeof(int64_t));

    for (int i = 0; i < array_size; i++) {
        array[i] = i + 1;
    }
    for (int i = 0; i < array_size; i++) {
        printf("%li ", array[i]);
    }
    printf("\n");

    array_size = array_resize(&array, array_size, 15);
    
    for (int i = 0; i < array_size; i++) {
        array[i] = i + 1;
    }
    for (int i = 0; i < array_size; i++) {
        printf("%li ", array[i]);
    }
    printf("\n");
    free(array);

    return 0;
}

错误对应现象解释

  • 当resize_num=15时,实际只分配了15个元素的内存,但你后续访问了25个元素,这属于内存越界访问,只是刚好这段内存没被其他数据覆盖,所以输出看起来正常,但这是典型的未定义行为,随时可能出错。
  • 当resize_num=5时,分配的内存只有5个元素,访问第11到15个元素时越界,读取到内存中的随机垃圾数据,所以出现乱码。
  • 当resize_num=130时,free(temp)释放了数组内存,后续赋值和打印都是在操作已释放的内存,最后main里再次free(array)就触发了双重释放错误,导致程序崩溃。

内容的提问来源于stack exchange,提问作者bugwriter123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:28:10