2010-02-21 5 views
0

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

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, кажется, работает в выкрикивая одно значение правильно, но когда я пытаюсь неоднократно называть свою функцию спискупоиска в цикле, как так:

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

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

ответ

2

Удалить ведущий «*» из firstMeeting:

missedFirstMeeting = SearchList((char *)registrants[i], (char **)attendees, attendeeCount); 
0

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

1

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

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

Я думал, что должен использовать *, чтобы сказать, что я хочу, чтобы значение missedFirstMeeting было установлено на возвращаемое значение SearchList, но, я думаю, это неверно. Но делая это с помощью цикла for, пропущенныйFirstMeeting получает только указатель на один элемент за раз? И если бы я сделал что-то вроде missedFirstmMeeting [i], то это был бы массив значений? – Crystal

+0

Я отредактировал свой ответ, чтобы показать, как вы сделали бы, чтобы сохранить все результаты в массиве. – Juan

0

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

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

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

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

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

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

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

Литье с указателем просто трудно прочитать.

+0

Сравнение правильное. 'bsearch' просматривает переменную' char ** ', поэтому, когда он хочет сравнить ключ с i-м элементом, он будет выполнять' Compare (key, haystack + i * size) ', передавая таким образом' char ** ' 'не' char * 'в обоих аргументах. – Juan

+0

«Сравнение» не обязательно в первую очередь. OP может просто передать 'strcmp' в' qsort' и 'bsearch'. – qrdl

+0

@Juan, вы правы, спасибо. – mctylr

0

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

Смежные вопросы