C 分配和排序指向现有结构的指针数组

C 分配和排序指向现有结构的指针数组,c,arrays,pointers,struct,C,Arrays,Pointers,Struct,我有一个预先分配的结构数组。我试图构造一个函数,它使用该数组作为输入,这样我就可以构造一个指向预分配结构数组的指针数组。然后我想使用qsort对指针数组进行排序,但我似乎误解了指针是如何传递的,因为当我试图运行代码时,这是内存访问冲突的雷区 第一个问题似乎是这样的: (&(pRet->ppIndexArray))[i]=&pTestElement[i] 在sortedIndexPointer中,我的想法是ppIndexArray是指向指针数组的指针,我需要获取ppIndexArray指向的数组的

我有一个预先分配的结构数组。我试图构造一个函数,它使用该数组作为输入,这样我就可以构造一个指向预分配结构数组的指针数组。然后我想使用qsort对指针数组进行排序,但我似乎误解了指针是如何传递的,因为当我试图运行代码时,这是内存访问冲突的雷区

第一个问题似乎是这样的:
(&(pRet->ppIndexArray))[i]=&pTestElement[i]
在sortedIndexPointer中,我的想法是ppIndexArray是指向指针数组的指针,我需要获取ppIndexArray指向的数组的地址,然后将当前TestElement的地址写入该数组,但这似乎不正确

请参阅下面我的简化代码:

#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);
}
#包括
#包括
typedef int(*比较函数)(常量无效*,常量无效*);
类型定义结构测试元素
{
常量字符*pName;
双重数据;
}测试元素;
typedef struct TestElementIndex
{
无符号元素计数;
测试元素**索引数组;
}测试员指数;
整数比较枚举(常量无效*p1,常量无效*p2){
TestElement*pTest1=*(TestElement**)p1;
TestElement*pTest2=*(TestElement**)p2;
如果(pTest1->数据>pTest2->数据){
返回1;
}
else if(pTest1->datadata){
返回-1;
}
否则{
返回0;
}
}
TestElementIndex*SortedIndex指针(TestElement*pTestElement,常量无符号计数,
比较函数(比较器){
TestElementIndex*pRet=malloc(sizeof(TestElementIndex));
pRet->elementCount=计数;
pRet->ppIndexArray=malloc(sizeof(TestElement*)*Count);
for(无符号i=0;ippIndexArray))[i]=&pTestElement[i];
}
if(比较器){
qsort(pRet->ppIndexArray,sizeof(TestElement*),Count,comparer);
}
返回pRet;
}
无效显示元素(常量TestElementIndex*pTestElementIndex){
对于(无符号i=0;ielementCount;i++){
printf(“%lf\n”,
pTestElementIndex->ppIndexArray[i]->数据);
}
}
int main(){
测试元素arr[]={
{“Test1”,5},
{“Test2”,8},
{“Test3”,4},
{“Test4”,9},
{“Test5”,1},
{“Test6”,2},
{“Test7”,0},
{“Test8”,7},
{“Test9”,3},
{“Test10”,6}
};
无符号计数=sizeof(arr)/sizeof(arr[0]);
TestElementIndex*pSorted=SortedIndex指针(arr、计数、比较枚举);
显示元素(pSorted);
}

代码中几乎没有问题:首先,qsort参数的顺序不同,您希望调用

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

接下来,在填充索引数组时,您不希望获取(address of)数组的地址,而是希望获取数组本身

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

否则,这基本上是合理的,请检查。

您应该做的第一件事是在调试器中研究各种指针。我敢打赌,10分钟的调试时间将准确地告诉您指针出错的地方。其他人会试图在同一时间检查你的代码,但你应该能够很快得到自己的答案。真棒,谢谢!我认为Q排序参数是我运行的圈子。让我善意地建议C++,因为它没有这样的问题(编译器会告诉你你的论点是错误的)。我知道,通常使用C++,但是在这个例子中,这个项目要求我使用C,相信我,我希望我能!
for (unsigned i = 0; i < Count; i++) {
    pRet->ppIndexArray[i] = &pTestElement[i];
}