0

I have an array of preallocated structs. I am attempting to construct a function which uses that array as input so that I can construct an array of pointers to preallocated struct array. I then want to sort the pointer array using qsort, but I seem to be misunderstanding how the pointers are passed around as when I try to run my code, it is a minefield of memory access violations.

The first issue seems to be with the line: (&(pRet->ppIndexArray))[i] = &pTestElement[i]; in sortedIndexPointer my thinking was that ppIndexArray is a pointer to an array of pointers, and I need to get the address of the array pointed to by ppIndexArray and then write the address of the current TestElement to that, but that seems to not be right.

Please see my simplified code below:

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

typedef int(*CompareFunction)(const void *, const void *);

typedef struct TestElement
{
    const char *pName;
    double data;
} TestElement;

typedef struct TestElementIndex
{
    unsigned elementCount;
    TestElement **ppIndexArray;
} TestElementIndex;

int CompareNumbers(const void *p1, const void *p2) {
    TestElement *pTest1 = *(TestElement **)p1;
    TestElement *pTest2 = *(TestElement **)p2;
    if (pTest1->data > pTest2->data) {
        return 1;
    }
    else if (pTest1->data < pTest2->data) {
        return -1;
    }
    else {
        return 0;
    }
}

TestElementIndex *sortedIndexPointer(TestElement *pTestElement, const unsigned Count,
                                     CompareFunction comparer) {
    TestElementIndex *pRet = malloc(sizeof(TestElementIndex));
    pRet->elementCount = Count;
    pRet->ppIndexArray = malloc(sizeof(TestElement *)*Count);

    for (unsigned i = 0; i < Count; i++) {
        (&(pRet->ppIndexArray))[i] = &pTestElement[i];
    }

    if (comparer) {
        qsort(pRet->ppIndexArray, sizeof(TestElement *), Count, comparer);
    }
    return pRet;
}

void DisplayElements(const TestElementIndex *pTestElementIndex) {
    for (unsigned i = 0; i < pTestElementIndex->elementCount; i++) {
        printf("%lf\n",
            pTestElementIndex->ppIndexArray[i]->data);
    }
}

int main() {
    TestElement arr[] = {
        { "Test1", 5 },
        { "Test2", 8 },
        { "Test3", 4 },
        { "Test4", 9 },
        { "Test5", 1 },
        { "Test6", 2 },
        { "Test7", 0 },
        { "Test8", 7 },
        { "Test9", 3 },
        { "Test10", 6 }
    };
    unsigned Count = sizeof(arr) / sizeof(arr[0]);
    TestElementIndex *pSorted = sortedIndexPointer(arr, Count, CompareNumbers);
    DisplayElements(pSorted);
}
1
  • The first thing you should do is to study your various pointers in a debugger. I am willing to bet that 10 minutes of debug time will show you exactly where your pointers are going awry. Others will attempt to back check your code in the mean time, but you should be able to get the answers pretty quickly on your own. Commented Feb 2, 2017 at 18:26

1 Answer 1

1

There are few problems with your code: first, qsort arguments have a different order, you wanted to call

qsort(pRet->ppIndexArray, Count, sizeof(TestElement *), comparer);

not

qsort(pRet->ppIndexArray, sizeof(TestElement *), Count, comparer);

Next, when filling the index array, you don't want to take the address of (address of) array, you want the array itself,

for (unsigned i = 0; i < Count; i++) {
    pRet->ppIndexArray[i] = &pTestElement[i];
}

Otherwise it is mostly reasonable, check http://cpp.sh/5mrxh.

Sign up to request clarification or add additional context in comments.

3 Comments

Awesome thanks! I think the qsort arguments are what had me running in circles.
Let me kindly suggest C++ then as it has no such problem (compiler will tell you your arguments are wrong).
I am aware, and normally use C++ but in this instance the project required me to use C, trust me I wish I could!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.