#c
#c
Вопрос:
Код пытается найти максимально возможное число из массива заданных чисел, используя массив символов вместо массива int. В моем сообщении о сборке нет ни предупреждений, ни ошибок. Тем не менее, когда я запускал этот код, он вылетает. Что-то не так в моем коде?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp(const void *a, const void *b){
const char **X = (const char **)a;
const char **Y = (const char **)b;
int char_len = strlen(*X) strlen(*Y) 1;
char XY[char_len];
strcpy(XY, *X);
strcat(XY, *Y);
char YX[char_len];
strcpy(YX, *Y);
strcat(YX, *X);
return strcmp(YX, XY);
}
int main (void) {
int i,n;
printf("enter number of salaries: ");
scanf("%d", amp;n);
char *array[n];
int j = sizeof(array)/sizeof(array[0]);
printf("nenter the salaries: ");
for(i=0; i<n; i ){
scanf("t%s", amp;array[i]);
}
printf("nOutput: n");
qsort(array, j, sizeof(array[0]), cmp);
for(i=0;i<n;i ){
printf("%s", array[i]);
return 0;
}
}
Редактировать 1: я переместил массив * char[n] после сканирования, если это сработало. Тем не менее, он по-прежнему выходит из строя при выполнении строки qsort.
Комментарии:
1.
n; char *array[n];
— сколько элементов имеетarray
? (т.е.. каково значениеn
whenarray
определено?)2. я вижу, я понимаю, я попытался переместить *array[n] после scanf . Теперь код выполняется и выводит данные из размера массива, элементов массива. Тем не менее, все еще происходит сбой в строке qsort.
3.
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
— получите лучший компилятор
Ответ №1:
Основная проблема, с которой вы сталкиваетесь, заключается в следующем:
scanf("t%s", amp;array[i]);
array
это массив указателей, и это передаст адрес одного из этих указателей в scanf, где %s
будет записана строка поверх указателя (давая вам указатель мусора и, если строка достаточно длинная, записывая дополнительные указатели в массиве.
Что вы хотите, так это выделить некоторую память для строки и прочитать ее в нее, а затем сохранить указатель на эту память в массиве. Если вы используете систему POSIX, есть простой способ сделать это:
scanf("t%ms", amp;array[i]);
Это будет использовать malloc для выделения ровно достаточного объема памяти для чтения строки (включая нулевой терминатор) и сохранения этого указателя в указанном элементе массива.
Также обратите внимание, t
что строка формата не имеет значения — она просто пропускает начальные пробелы, что спецификатор s
преобразования делает в любом случае.
Ответ №2:
n
не инициализируется. Следовательно, неопределенное поведение при объявлении array[n]
int i,n;
char *array[n];
int j = sizeof(array)/sizeof(array[0]);
Представьте, был ли n
присвоен ноль при запуске. Изменение значения n в следующей scanf
строке не приведет к изменению размера массива.
Кроме того, даже если n
была достаточно назначена длина массива, это все еще неопределенное поведение:
for(i=0; i<n; i ){
scanf("t%s", amp;array[i]);
}
Для каждой записи массива не выделяется память. Представьте, что после char* array[n]
успешного объявления каждое значение указателя в этом массиве не определено. ЕСЛИ вам повезет, каждый элемент имеет значение NULL (0), и он быстро завершится сбоем. Но, скорее всего, вы получаете случайную память. И вы scanf
копируете строку в память, которой ваша программа не владеет.
Комментарии:
1. понятно, большое вам спасибо. Я попытался переместить оба int i,n; char *array[n]; после сканирования, это работает! но все равно происходит сбой при выполнении строки qsort.
2. Потому что вы не выделили достаточно памяти для каждого элемента в массиве. Как вы думаете, на какой адрес
scanf("t%s", amp;array[i]);
копируется введенный пользователем ввод? Вы знаете, чтоmalloc
делает?