【问题标题】:Why am I getting errors when debugging realloc?为什么调试 realloc 时会出错?
【发布时间】:2022-01-17 00:21:15
【问题描述】:
int *dynArr(int* arr, int n, int isEven) {
    int count = 0;
    int* t = (int*)calloc(n, sizeof(int));
    assert(t);
    if (isEven == 1) {
        for (int i = 0; i < n; i++) {
            if (arr[i] % 2 == 0) {
                t[count++] = arr[i];
            }
        }
    }
    t = (int*)realloc(*t, count * sizeof(int));
    return t;
}

void main() {
    int a[] = { 1,8,3,6,11 };
    int n = sizeof(a) / sizeof(int);
    int isEven = 1;
    int* arr = dynArr(a, n, isEven);
    for (int i = 0; i < n; i++) {
        printf("%d", arr[i]);
    }
}

问题是当我返回数组时我没有得到任何输出,当我调试时我得到这个错误:“homelab8.exe 中 0x7A08B54D (ucrtbased.dll) 处的未处理异常:0xC0000005: 访问冲突读取位置 0x00000004。” 有人知道我该如何解决这个问题?

【问题讨论】:

  • 启用编译器的警告! (我用-Wall -Wextra -pedantic配合gcc和clang。)发现两个问题,一个大问题。
  • t = (int*)realloc(*t, count * sizeof(int)); 中,您传递的*tt[0] 相同。您应该传递一个指向已分配内存块的指针,即 t
  • 如果代码是在定义NDEBUG 的情况下编译的,那么assert(t); 会发生什么?教你使用assert() 进行必要的错误检查的人是被误导的。
  • 你访问元素0..n-1,但是你使用realloc创建了一个只包含count元素的数组,数量比n
  • 在任何情况下realloc 可能会失败,但是您的代码会产生内存泄漏:t 指向尚未存在的数组的旧值被NULL 覆盖。从一开始就习惯于做正确的事:temporary = realloc(current); if(temporary) { current = temporary; } else { /* some appropriate error handling; if need be, still can use old value of current – even if you only free it */ }

标签: arrays c realloc


【解决方案1】:

首先,您将错误的参数传递给realloc。如果您一直使用编译器的警告,这很容易被发现。

另一个主要问题是您正在访问arr 指向的数组的n 元素,但它没有n 元素。

由于要返回两个值,因此需要通过参数返回(或返回结构)。

// Returns 0 on success.
// Returns -1 and sets errno on error.
int filter_even_or_odd(
    int **filtered_arr_ptr,  // The address of a variable that accepts output.
    size_t *filtered_n_ptr,  // The address of a variable that accepts output.
    int *arr,
    size_t n,
    int keep_even            // Keep even or keep odd?
) {
    size_t filtered_n = 0;
    int *filtered_arr = malloc( sizeof(int) * n );
    if (!filtered_arr)
        return -1;

    int to_keep = keep_even ? 0 : 1;
    for ( size_t i = 0; i < n; i++ ) {
        if ( arr[i] % 2 == to_keep ) {
            filtered_arr[ filtered_n++ ] = arr[i];
        }
    }

    int *tmp = realloc( filtered_arr, sizeof(int) * filtered_n );
    if (tmp)
        filtered_arr = tmp;

    *filtered_arr_ptr = filtered_arr;
    *filtered_n_ptr   = filtered_n;
    return 0;
}

【讨论】:

  • 谢谢它的工作:)
猜你喜欢
  • 1970-01-01
  • 2015-01-27
  • 2022-07-22
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多