У меня есть следующая функция сравнения:
int compareByMemSize(const void *a, const void *b)
{
const struct ProcInfo *procInfo1 = (const struct ProcInfo *) a;
const struct ProcInfo *procInfo2 = (const struct ProcInfo *) b;
if (( procInfo1->memSize != NULL && procInfo1->memSize[0] != '\0' ) && ( procInfo2->memSize != NULL && procInfo2->memSize[0] != '\0' ))
{
long memSize1 = strtol(procInfo1->memSize, NULL, 10);
long memSize2 = strtol(procInfo2->memSize, NULL, 10);
if (memSize1 < memSize2)
return -1;
if (memSize1 > memSize2)
return 1;
return 0;
}
if (procInfo1->memSize == NULL && procInfo2->memSize == NULL)
return 0;
if (procInfo1->memSize == NULL)
return -1;
return 1;
}
это выполняет логику сравнения для следующей структуры:
typedef struct ProcInfo {
int PID;
char *name;
char *memSize;
} ProcInfo;
и я вызываю qsort следующим образом:
qsort(&a, sizeof(a), sizeof(ProcInfo), compareByMemSize);
где a имеет тип ProcArray:
typedef struct ProcArray {
ProcInfo *array;
size_t used;
size_t size;
} ProcArray;
результатом является ошибка сегмента, и я думаю, это связано с тем, что memSize может быть либо длинным символом, например: 122313131 (это char[], потому что изначально он содержит «kB», а я удалил «kB» для сравнения) или '\0'.
Некоторые значения memSize изначально также не существуют, поэтому я компенсировал это, установив для их char[] значение '\0', отсюда и проверка этого символа выше.
Я просто неправильно использую qsort? или мой подход к установке char[] в '\0', если значение не найдено неправильным?
Если потребуется больше кода, я буду более чем рад предоставить!
если требуется больше кода. Пожалуйста, опубликуйте Минимально воспроизводимый пример, кратчайший полный код, показывающий проблему.
Вызов qsort() совершенно неправильный. Возможно, вы сможете использовать qsort(a.array, a.used, sizeof(ProcInfo), compareByMemSize);, но это может быть по-другому. Вы передаете адрес a и сообщаете qsort(), что в массиве (вероятно) 24 элемента. Вам может сойти с рук передача адреса a, поскольку адрес структуры также является адресом первого элемента структуры, хотя эти два указателя относятся к разным типам. Но sizeof(a) будет размером структуры ProcArray в байтах, что совершенно не связано с размером массива.
И я вижу, что ответ Бармара говорит примерно то же самое, что и мой комментарий. Его ответа не было видно, когда я начал печатать свой комментарий.
P.S. вместо всех этих операторов if просто вычтите один элемент из другого.





a — это не массив ProcInfo, это отдельная структура ProcArray. Массив, который необходимо отсортировать, — это a.array.
qsort(a.array, a.used, sizeof(ProcInfo), compareByMemSize);
Вам не нужен & при передаче a.array, потому что это уже указатель.
потрясающе, не могу поверить, что я это пропустил. Я получаю выходные данные впервые, но числа полузашифрованы: большой сегмент отсортирован, за которым следуют несортированные сегменты. Я думаю, что моя функция сравнения не идеальна, но спасибо!
Первый оператор if проверяет, является ли memSize нулевым указателем или указывает на пустую строку. Более поздние операторы if проверяют только нулевые указатели, а не пустые строки.
Почему вы сохраняете memSize как строку, а не анализируете ее до целого числа при создании структуры?
изначально, когда я читаю его из файла, он содержит «КБ», поэтому я сохраняю его как char[]. должен ли я установить это свойство как целое число и сразу же выполнять манипуляции со строками? после прочтения из файла?
Да, это то, что я предлагаю.
Этот совет мне очень помог, и в итоге я создал два массива: один для значений NULL, а другой — без. Я столкнулся с проблемами, когда некоторые значения, которые не были NULL, все еще помещались в массив для значений, отличных от NULL или '\0', и каким-то образом преобразование char[] в int как можно скорее устранило эту проблему, память действительно сложно..но увлекательно
Я думал, что вы могли бы просто установить длину по умолчанию равной 0, когда она равна нулю.
Давайте продолжим обсуждение в чате.
Ваш
sizeof(a)не дает вам количества элементов массива.