2015-05-06 4 views
1

В стандартной qsort() функции, объявленной в <stdlib.h>, он выходит из строя, когда я делаю следующее:Путаница между полукокса * и полукокса [] в QSort()

char *arr[]={"abc","def"}; 
qsort((void*)arr[i],strlen(arr[i]),sizeof(char),compare); 

Для того, чтобы работать, я должен использовать его как это:

int len=strlen(arr[i]); 
char *buffer=new char[len+1]; 
strcpy(buffer, arr[i]);   
qsort((void*)buffer,strlen(arr[i]),sizeof(char),compare); 

Почему первый способ не работает, когда декларация qsort() также указывает void* в качестве первого аргумента?

Я знаю, что в первом методе то, что я передаю, не является массивом, но не char* всегда рассматривается как массив?

Если нет, то каковы случаи, когда он не рассматривается как массив?

+0

символ * всегда рассматривается как символ *, его только, что нет никакой реальной поддержки строк в C, поэтому они остановились на символ *, представляющий строку. Кроме того, ваш вопрос помечен как C++, поэтому, пожалуйста, рассмотрите использование std :: string и std :: sort вместо – Creris

+0

Вам не нужно указывать * на * 'void *', а второй параметр - количество, которое нужно сортировать * (так что be 2, а не 3). – crashmstr

+0

@Creris: Это не совсем так. C поддерживает строки; просто нет типа данных, называемого 'string'. Строка по определению является «непрерывной последовательностью символов, заканчивающихся и включающих первый нулевой символ». Символ 'char *' не является строкой, хотя может указывать на строку. –

ответ

3

Элементы массива arr являются неконстантными указателями на строковые константы. Попытка изменить то, на что указывает (т. Е. Строковая константа) через qsort(), дает неопределенное поведение. Это отличается от сценария char p[] = "some string";, и в этом случае вы инициализируете массив p содержимым строкового литерала, тогда вы можете без проблем изменить код p. Правильное определение char* arr[] должно быть const char* arr[], чтобы предотвратить такие проблемы.

Если вы собираете со всеми предупреждениями и с компилятором C++ вы должны получить предупреждение похожего на

предупреждения: ISO C++ запрещает преобразование строки константы «символ *» [-Wpedantic]

Простой компилятор C, похоже, не выдал никаких предупреждений, но это по-прежнему неопределенное поведение.

тесно связаны: Why do I get a segmentation fault when writing to a string initialized with "char *s" but not "char s[]"? и Modifying C string constants?

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