Void pointer values inexplicably changing between function calls

67 views Asked by At

Okay, so the code I am referring to is below. It isn't the whole code, but it is the pertinent parts

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;
 }

The intent of the functions doesn't matter, and I have removed irrelevant parts, but the problem areas are above. My issue is that the user calls array_sort with an array of doubles and num_ascending as the comparison function. The problem is when the if statement is called, and it passes the addresses A + i and max to the comparison function, the values at the A + i location always changes to 0 if i is greater than 0, regardless of how big the original array A[] is.

The thing is, I've used a series of print statements to track a call. BEFORE the comparison call, the value at A + 1 is 1.00, and immediately within the call to num_ascending(), it reads as 0.00. I verified that the void pointer we're passing does not change, as in the address DOES get passed perfectly, but the value at that address has just gone to 0. It hasn't for the void* max. I'm just completely unsure as to why this is happening. Any help would be greatly appreciated!

1

There are 1 answers

5
Creative Mania On BEST ANSWER

The issue you're encountering seems to stem from how you're accessing elements within the array of doubles in the array_sort function. Let's take a closer look at your array_sort function:

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;
        }
    }
}

When you add i to the void* A pointer in comparison(A + i, max), you're essentially moving the pointer forward by i times the size of the data type it points to. This might not be what you intend to do.

If A points to an array of doubles, incrementing A by i would move the pointer forward by i * sizeof(double) bytes, which is not what you want for accessing elements within the array.

Instead, you should use array indexing to access elements within the array. Here's how you can correct the array_sort function:

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);
        }
    }
}

In this corrected version, we use i to index into the array by multiplying i with sizeof(double). This ensures that we're correctly accessing each element within the array of doubles. The cast to (char*) is necessary to perform pointer arithmetic properly, as incrementing a void* is not allowed in C.