2013-11-22 3 views
1

У меня есть-структура:Получение «Ошибка: недопустимый инициализатор» при вызове bsearch

typedef struct DATA { 
    char *key; 
    char *parentKey; 
    char *description; 
} DATA; 

И массив экземпляров:

DATA *data_array = NULL; // the global data array 
int m_arrayLength = 0; // Keeps track of the number of elements used 

После того, как массив заполняется Я его сортировкой с помощью qsort

void SortData() 
{ 
    qsort(data_array, m_arrayLength, sizeof(DATA), CompareDataByKey); 
} 

int CompareDataByKey(const void *a, const void *b) 
{ 
    DATA *ia = (DATA *)a; 
    DATA *ib = (DATA *)b; 
    return strcmp(ia->key, ib->key); 
} 

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

DATA FindDataByKey(char *key) 
{ 
    DATA *searchData = malloc(sizeof(DATA)); 

    searchData->key = key; 

    DATA result = bsearch(
     searchData, 
     data_array, 
     m_arrayLength, 
     sizeof(DATA), 
     CompareDataByKey); 

    free(searchData); 

    return result; 
} 

gcc компилятор возвращается сообщение:

p_CONNECT.c: In function 'FindDataByKey':

p_CONNECT.c:87: error: invalid initializer

make: The error code from the last command is 1.

на линии CompareDataByKey);

Может ли кто-нибудь объяснить смысл этой ошибки в контексте кода, который я написал?

+0

Что такое подпись функции «bsearch»? Должен ли быть отправлен адрес метода? Я думаю, что должен быть & CompareDataByKey –

ответ

4

Вы отбрасываете номер строки, указанный компилятором. Сообщение «неправильный инициализатор» относится ко всей инициализации/выражению DATA result = bsearch(...), которое заканчивает последним аргументом, а не последним аргументом.

Инициализатор неверен, потому что result объявлен как DATA (a struct), а bsearch возвращает указатель. Чтобы исправить это, объявить result как указатель:

DATA *result = bsearch(
     searchData, 
     data_array, 
     m_arrayLength, 
     sizeof(DATA), 
     CompareDataByKey); 

Когда вы исправить это, необходимо также изменить FindDataByKey вернуть DATA *, не DATA. Несколько несвязанных кодирования замечания:

  • Вам не нужно malloc поиска данных при вызове bsearch, вы можете просто инициализировать его в стек и передать адрес переменной функции. Например:

    DATA searchData; 
    searchData.key = key; 
    return bsearch(&searchData, ...); 
    
  • Если вы звоните malloc, не забудьте проверить возвращаемое значение. Вызов malloc может завершиться неудачей, и рекомендуется сообщить об этом пользователю. (Общепринятый способ сделать это путем создания обертку под названием что-то вроде xmalloc, который вызывает malloc, проверяет свой результат и выводит сообщение об ошибке и вызывает exit(), если результат равен NULL.)

  • Приставка глобальную переменную m_ путает пользователей, исходящих из фона C++, где префикс m_ обозначает членов класса.

+0

В mathoc был добавлен в мою борьбу за решение проблемы и поэтому был удален. Должны ли мы использовать 'g_' вместо' m_'? – qujck

+1

@qujck Нет единого соглашения.Многие C-коды различают глобальные и локальные имена, просто глобальными являются длинными и описательными (например, 'common_data_array' или whatnot), а локальные - короткими (' array' или 'arr'). Независимо от того, что вы выберете, просто избегайте 'm_', который является хорошо установленным соглашением с другим значением в C++. – user4815162342

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