EXC_BAD_ACCESS 在 C 中的结构中对字符数组使用 QSort

EXC_BAD_ACCESS using QSort on an Array of Chars within Structs in C

我搜索了此处的许多答案并基于此进行了一些更改,但在调用 qsort 函数时出现 EXC_BAD_ACCESS 错误。我的 IDE 指向我的 qsort 比较函数中的 return 作为问题。我知道我正在为所有元素正确分配内存,因为如果我省略对 qsort 的调用,我可以毫无问题地打印字符串。有人能给我指出正确的方向吗?

我的结构,看看我导航的深度:

typedef struct {
    unsigned int siteId;
    unsigned int tableTypeId;
    unsigned int surMatId;
    unsigned int strucMatId;
    char *streetAve;
    unsigned int neighbourhoodId;
    char *neighbourhoodName;
    unsigned int ward;
    char *latitude;
    char *longitude;
} Entries;

typedef struct {
    int size;
    Entries **entry;
} PicnicTable;

typedef struct {
    Table *tableTypeTable;
    Table *surfaceMaterialTable;
    Table *structuralMaterialTable;
    NeighbourHoodTable *neighborhoodTable;
    PicnicTable *picnicTableTable;
} DataBase;

extern DataBase *DB;




Entries **ent = DB->picnicTableTable->entry;
qsort(ent,DB->picnicTableTable->size-1, sizeof(Entries*), cmpfunc); typedef struct {
    unsigned int siteId;
    unsigned int tableTypeId;
    unsigned int surMatId;
    unsigned int strucMatId;
    char *streetAve;
    unsigned int neighbourhoodId;
    char *neighbourhoodName;
    unsigned int ward;
    char *latitude;
    char *longitude;
} Entries;

typedef struct {
    int size;
    Entries **entry;
} PicnicTable;

typedef struct {
    Table *tableTypeTable;
    Table *surfaceMaterialTable;
    Table *structuralMaterialTable;
    NeighbourHoodTable *neighborhoodTable;
    PicnicTable *picnicTableTable;
} DataBase;

extern DataBase *DB;

电话是这样的:

Entries **ent = DB->picnicTableTable->entry;
qsort(ent,DB->picnicTableTable->size-1, sizeof(Entries*), cmpfunc);

比较函数是:

int cmpfunc(const void *a, const void *b) { 
    Entries *left = *(Entries**)a;
    Entries *right = *(Entries**)b;

    return strcmp(left->neighbourhoodName, right->neighbourhoodName);
}

picnicTableTable 和 Entry 在这个 malloc 之后被初始化:

DB->picnicTableTable = malloc(sizeof(PicnicTable));
DB->picnicTableTable->entry = malloc(numEntries*sizeof(Entries)+1);
DB->picnicTableTable->size = numEntries;

while ((c=fgetc(IN)) != EOF) {
        if (c == ',' && row > 0) {
            switch (column) {
                case 0: neighbourhoodName = copyToChar(buff, begin, i);
...
}

copyToChar 获取缓冲区的一部分并分配内存,然后 returns 一个指向我分配的值的指针:

char * copyToChar(const char * buff, int begin, int end) {
    char *temp = malloc(end - begin + 1);
    int j = 0;

    for (int i = begin; i < end; i++, j++)
        temp[j] = buff[i];
    temp[j] = '[=15=]';

    return temp;
}

在我遍历文件中的每一行后填充数组(这只是一个条目):

DB->picnicTableTable->entry[row]->neighbourhoodName = malloc(strlen(neighbourhoodName)*sizeof(char)+1);

a->neighbourhoodName 的值为 NULL,这让我很困惑。 qsort 不会将数组中的两个值传递给比较函数吗?

感谢您的宝贵时间!

当心。您将 entry 声明为指向指针的指针(指向指针数组的第一个元素)

typedef struct {
    int size;
    Entries **entry;
} PicnicTable;

但将其初始化为一个动态数组,即指向 Entrys 数组第一个元素的指针:

DB->picnicTableTable->entry = malloc(numEntries*sizeof(Entries)+1);

如果你想要一个指针数组来加速qsort,你应该单独构建它:

typedef struct {
    int size;
    Entries *entry;
    Entries **pentry;
} PicnicTable;

DB->picnicTableTable->entry = malloc(numEntries*sizeof(Entries)+1);
DB->picnicTableTable->pentry = malloc(numEntries*sizeof(&Entries)+1);
for (int i=0; i<=numEntries; i++) { // initialize the array of pointers
    pentry[i] = entry + i;
}

目前 cmpfunc 的定义与您对 DB->picnicTableTable->entry 的初始化不一致。