Путаница между 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?

Другие вопросы по тегам