C qsort fn ошибка сегментации

У меня есть следующая функция сравнения:

  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', если значение не найдено неправильным?

Если потребуется больше кода, я буду более чем рад предоставить!

Ваш sizeof(a) не дает вам количества элементов массива.

Weather Vane 16.05.2024 22:48

если требуется больше кода. Пожалуйста, опубликуйте Минимально воспроизводимый пример, кратчайший полный код, показывающий проблему.

Weather Vane 16.05.2024 22:52

Вызов qsort() совершенно неправильный. Возможно, вы сможете использовать qsort(a.array, a.used, sizeof(ProcInfo), compareByMemSize);, но это может быть по-другому. Вы передаете адрес a и сообщаете qsort(), что в массиве (вероятно) 24 элемента. Вам может сойти с рук передача адреса a, поскольку адрес структуры также является адресом первого элемента структуры, хотя эти два указателя относятся к разным типам. Но sizeof(a) будет размером структуры ProcArray в байтах, что совершенно не связано с размером массива.

Jonathan Leffler 16.05.2024 23:03

И я вижу, что ответ Бармара говорит примерно то же самое, что и мой комментарий. Его ответа не было видно, когда я начал печатать свой комментарий.

Jonathan Leffler 17.05.2024 00:27

P.S. вместо всех этих операторов if просто вычтите один элемент из другого.

CPlus 17.05.2024 00:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

a — это не массив ProcInfo, это отдельная структура ProcArray. Массив, который необходимо отсортировать, — это a.array.

qsort(a.array, a.used, sizeof(ProcInfo), compareByMemSize);

Вам не нужен & при передаче a.array, потому что это уже указатель.

потрясающе, не могу поверить, что я это пропустил. Я получаю выходные данные впервые, но числа полузашифрованы: большой сегмент отсортирован, за которым следуют несортированные сегменты. Я думаю, что моя функция сравнения не идеальна, но спасибо!

Mathew 16.05.2024 23:03

Первый оператор if проверяет, является ли memSize нулевым указателем или указывает на пустую строку. Более поздние операторы if проверяют только нулевые указатели, а не пустые строки.

Barmar 16.05.2024 23:06

Почему вы сохраняете memSize как строку, а не анализируете ее до целого числа при создании структуры?

Barmar 16.05.2024 23:07

изначально, когда я читаю его из файла, он содержит «КБ», поэтому я сохраняю его как char[]. должен ли я установить это свойство как целое число и сразу же выполнять манипуляции со строками? после прочтения из файла?

Mathew 16.05.2024 23:08

Да, это то, что я предлагаю.

Barmar 16.05.2024 23:23

Этот совет мне очень помог, и в итоге я создал два массива: один для значений NULL, а другой — без. Я столкнулся с проблемами, когда некоторые значения, которые не были NULL, все еще помещались в массив для значений, отличных от NULL или '\0', и каким-то образом преобразование char[] в int как можно скорее устранило эту проблему, память действительно сложно..но увлекательно

Mathew 17.05.2024 00:01

Я думал, что вы могли бы просто установить длину по умолчанию равной 0, когда она равна нулю.

Barmar 17.05.2024 00:03

Давайте продолжим обсуждение в чате.

Mathew 17.05.2024 04:38

Другие вопросы по теме