Помогите с ошибкой сегментации в функции - PullRequest
0 голосов
/ 21 февраля 2010

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

int Compare(const void *a, const void *b);

void SortStudents(char *studentList[], size_t studentCount) 
{
    qsort(studentList, studentCount, sizeof(studentList[0]), Compare);
}

int Compare(const void *a, const void *b) 
{
    return (strcmp(*(char **)a, *(char **)b));
}

char *SearchList(char *key, char *list[], size_t num) 
{
    char **value = bsearch(&key, list, num, sizeof(list[0]), Compare);
    return (value == 0 ? 0 : *value);
}

/*Determines which registrants did not attend the first meeting by searching for registrants 
 that are not in attendees set. */
void DisplayClassStatus(
                        const char *registrants[], size_t registrantCount,
                        const char *attendees[],   size_t attendeeCount)
{
    char *missedFirstMeeting = SearchList((char *)registrants[0], (char **)attendees, attendeeCount);
}

Кажется, что мой missedFirstMeeting работает для правильного вызова одного значения, но когда я пытаюсь многократно вызывать свою функцию SearchList в цикле следующим образом:

for (int i = 0; i < attendeeCount; i++) {
    *missedFirstMeeting = SearchList((char *)registrants[i], (char **)attendees, attendeeCount);
}

Я получаю ошибку ошибки сегментации. Мне кажется, что я делаю то же самое, но просто неоднократно вызываю SearchList (), но, очевидно, что-то не так, что я не вижу, так как я получаю эту ошибку ошибки сегментации. Есть идеи? Спасибо.

Ответы [ 5 ]

2 голосов
/ 21 февраля 2010

Удалить ведущий '*' firstMeeting:

missedFirstMeeting = SearchList((char *)registrants[i], (char **)attendees, attendeeCount);
1 голос
/ 21 февраля 2010

Хорошо, проблема в следующем, вы перебираете registrants, но вы останавливаетесь, когда обрабатываете attendeeCount элементов. А также, если missedFirstMeeting является символом *, сделайте, как сказал тур1нг, вам нужно удалить ведущий *. Так что просто сделайте это:

for (int i = 0; i < registrantCount; i++) {
    missedFirstMeeting = SearchList((char *)registrants[i], (char **)attendees, attendeeCount);
    /* Code that uses missedFirstMeeting here */
}

Edit: Если вы хотите сохранить все возвращаемые значения SearchList, вы должны сделать что-то вроде этого:

char** missedFirstMeething = malloc(sizeof(char*)*registrantCount);
for (int i = 0; i < registrantCount; i++) {
    missedFirstMeeting[i] = SearchList((char *)registrants[i], (char **)attendees, attendeeCount);
}

Конечно, после того, как вы закончите использовать missedFirstMeeting, вы должны освободить выделенную память.

0 голосов
/ 22 февраля 2010

Проблема в том, что хотя компьютеры являются большими блоками изменяемой памяти, это не лучший способ представить их при программировании. Вы смоделировали компьютер таким образом, и он не совсем сработал.

0 голосов
/ 21 февраля 2010

Есть (по крайней мере) две проблемы, которые я вижу с вашим кодом.

Во-первых, тривиально, но важно то, что цикл for должен сравнивать i с registrantCount, а не attendeeCount.

Второе сравнение () должно быть записано:

int Compare(const void *a, const void *b) 
{
    return (strcmp((char *)a, *(char *)b));
}

Вам просто нужно привести указатели void к указателям на символы. Исправление этих ошибок должно исправить ваши ошибки SegFault.

Добавлено: Разыменование missedFirstMeeting в цикле for является одной из двух основных проблем.

  for (i = 0; i < registrantCount; i++) {
      missedFirstMeeting = SearchList((char *)registrants[i], (char **)attendees, attendeeCount);
  }

Приведение указателя просто трудно читать.

0 голосов
/ 21 февраля 2010

Хорошо, вам нужно поместить функции возвращаемых значений в переменную. Я пишу C ++ для жизни, мой босс никогда бы не принял такой код. Этот код очень трудно читать и еще сложнее отлаживать. Причина в том, что вы можете настроить часы для переменной. Вы также можете увидеть, как программа цепочки, когда вы шагаете через программу построчно. Отладчик выведет список всех переменных в вашем пространстве имен и их соответствующие значения. Бьюсь об заклад, деньги, что пока вы переписываете это, чтобы сделать его более читабельным, вы сами решите проблему.

...