[英]QSorting a malloc'd array of structures?
我在C中為我的qsort擁有此比較器功能,但無論嘗試如何,我似乎都遇到了分段錯誤。
int textCompare ( const void * a, const void * b ){
const char **x =(const char**)a;
const char **y =(const char**)b;
return strcmp(*x, *y);
}
這是我的qsort調用:其中message** mList = malloc(INITIAL_CAPACITY * sizeof(message));
count
是跟蹤最后一個元素的整數。 message只是一個typedef結構,包含一個int和一個指向char的指針。 我有67%的把握可以正確地撥打qsort,有人可以指出正確的方向嗎?
qsort (*mList, count, sizeof(message), textCompare);
[EDIT]我之所以聲明message ***而不是message *的原因是因為我正在嘗試初始化結構指針的“數組”; 除非我要以錯誤的方式處理?
如果您確實想對指向消息結構的指針數組進行排序,則需要使用此方法
message **mlist = (message **)malloc(INITIAL_CAPACITY * sizeof(message *));
然后,您必須為數組中的指針所指向的每條消息分配內存。
for(int i=0; i<INITIAL_CAPACITY; i++) {
mlist[i] = (message *)malloc(sizeof(message));
/* initialize the members here */
mlist[i]->int = get_int();
mlist[i]->char = get_char();
count++
if(count >= NUM_TO_FILL_RIGHT_NOW)
break;
}
現在您可以對指針數組而不是結構本身進行排序。
int textCompare( const void *a, const void *b ) {
message *m1 = *(message **)a;
message *m2 = *(message **)b;
return strcmp(m1->char, m2->char);
}
現在在指針數組上調用qsort
qsort( mlist, count, sizeof(message *), textCompare );
使用此方法,指針(在理論上)位於連續內存中,但是結構本身會根據需要進行單獨分配。 同樣,由於要復制的對象的大小,排序指針通常比排序結構更快。 指針在64位計算機上為8字節,在32位計算機上為4字節,您的結構實際上可能比該指針小,但是典型的結構將大於指針。
我不確定您對malloc()的調用是否為您要使用的內存分配了正確的內存類型。 您正在聲明一個指針數組,然后依次指向某個(可能的)指針數組,但似乎您是在為結構本身的實際大小保留內存,即,您正在為數組保留內存消息,而不是消息的指針數組。 例如,如果取消引用mlist,則結果指針指向什么? 是否要指向單個消息結構或消息結構數組(即,您具有一些消息結構的二維數組,其中mlist [0]至mlist [n]分別表示指向消息數組的指針在堆上是任意長度的)? 如果不是要指向任何東西,而是應該是一個實際的消息結構,那么您的呼叫應該看起來更像:
message* mlist = malloc(INITIAL_CAPACITY * sizeof(message));
而不是mlist是message**
類型。
希望這可以幫助。
@Jason和@Tim都給出了正確答案。 這是一個正確的,有效的程序,用來證明他們的答案。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct message {
int i;
char *p;
} message;
int textCompare(const void *a, const void *b) {
const message *ma = a;
const message *mb = b;
return strcmp(ma->p, mb->p);
}
int main()
{
int i;
message* mList = malloc(10 * sizeof(message));
mList[0].i = 0; mList[0].p = "zero";
mList[1].i = 1; mList[1].p = "one";
mList[2].i = 2; mList[2].p = "two";
qsort(mList, 3, sizeof(message), textCompare);
for(i = 0; i < 3; i++) {
printf("%d %s\n", mList[i].i, mList[i].p);
}
return 0;
}
請注意malloc
調用的模式。 分配類型T
的數組:
T* var = malloc(array_size * sizeof(T));
看看聲明中只有一個*
,而sizeof()運算符的星號要少一個。 有些人喜歡這種形式:
T* var = malloc(array_size * sizeof *var);
這樣,您只需指定一次類型即可。 這對於復雜類型特別有用。
另外,請注意,沒有對malloc
的結果進行malloc
。
另外,請注意qsort()的第一個arg的類型如何與compare函數中轉換后的參數的類型匹配。 在這種特定情況下,它們都是message*
。
您可能會發現此qsort調用更容易理解和維護:
qsort(mList, 3, sizeof(*mList), textCompare);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.