Путаница между char* и char[] в qsort()
В стандарте qsort()
функция объявлена в <stdlib.h>
, он падает, когда я делаю следующее:
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*
всегда рассматривается как массив?
Если нет, то в каких случаях он не рассматривается как массив?
1 ответ
Элементы массива arr
неконстантные указатели на строковые константы. Попытка изменить то, на что они указывают (то есть строковую константу) через qsort()
дает неопределенное поведение. Это отличается от сценария char p[] = "some string";
в этом случае вы инициализируете массив p
с содержанием строкового литерала, то вы можете изменить p
без проблем. Правильное определение char* arr[]
должно быть const char* arr[]
Именно для предотвращения подобных проблем.
Если вы компилируете все предупреждения на и с компилятором C++, вы должны получить предупреждение, подобное
предупреждение: ISO C++ запрещает преобразовывать строковую константу в 'char*' [-Wpedantic]
Простой компилятор C, похоже, не выдает предупреждений, но это все еще неопределенное поведение.
Близко связано: почему я получаю ошибку сегментации при записи в строку, инициализированную с "char *s", но не с "char s[]"? и изменение строковых констант C?