空指针值在函数调用之间莫名其妙地变化

问题描述 投票:0回答:1

好的,我引用的代码如下。这不是整个代码,而是相关部分

void
array_sort(void *A, int arr_size, int comparison(void *, void*)) {
    void *max = A;
    int i;
    for (i = 0; i < arr_size; i++) {
        if (comparison(A + i, max) == -1) {
            max = A + i;
        }
    }
}


int
num_ascending(void *n1, void *n2) {
    double v1 = *((double *) n1), v2 = *((double *) n2);
    if (v1 > v2) {
        return -1;
    } else if (v1 < v2) {
        return 1;
    }
    return 0;
 }

功能的意图并不重要,我已经删除了不相关的部分,但问题区域在上面。我的问题是用户使用双精度数组和 num_ascending 作为比较函数调用 array_sort 。问题是,当调用 if 语句并将地址 A + i 和 max 传递给比较函数时,如果 i 大于 0,则 A + i 位置的值始终更改为 0,无论原始值有多大数组 A[] 是。

问题是,我使用了一系列打印语句来跟踪呼叫。在比较调用之前,A + 1 处的值为 1.00,并且在调用 num_ascending() 后立即读取为 0.00。我验证了我们传递的 void 指针没有改变,因为地址中的值确实被完美地传递了,但该地址处的值刚刚变为 0。它没有达到 void* max 的值。我完全不确定为什么会发生这种情况。任何帮助将不胜感激!

function pointers void
1个回答
0
投票

您遇到的问题似乎源于您如何访问 array_sort 函数中双精度数组中的元素。让我们仔细看看你的 array_sort 函数:

void array_sort(void *A, int arr_size, int comparison(void *, void*)) {
    void *max = A;
    int i;
    for (i = 0; i < arr_size; i++) {
        if (comparison(A + i, max) == -1) {
            max = A + i;
        }
    }
}

当您将 i 添加到 void* A 指针进行比较(A + i, max)时,您实际上是将指针向前移动了它所指向的数据类型大小的 i 倍。这可能不是您想要做的。

如果 A 指向双精度数组,则将 A 递增 i 会将指针向前移动 i * sizeof(double) 字节,这不是您想要访问数组中的元素的情况。

相反,您应该使用数组索引来访问数组中的元素。以下是纠正 array_sort 函数的方法:

void array_sort(void *A, int arr_size, int comparison(void *, void*)) {
    void *max = A;
    int i;
    for (i = 0; i < arr_size; i++) {
        if (comparison((char *)A + i * sizeof(double), max) == -1) {
            max = (char *)A + i * sizeof(double);
        }
    }
}

在这个更正的版本中,我们通过将 i 乘以 sizeof(double) 来使用 i 来索引数组。这确保我们正确访问双精度数组中的每个元素。为了正确执行指针算术,必须强制转换为 (char*),因为 C 中不允许递增 void*。

© www.soinside.com 2019 - 2024. All rights reserved.