Я работаю над своим учебником C.
У меня есть такая функция:
void sortString(char c[][5], int size) {
char temp[] = "";
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - 1; j++)
{
if (strcmp(c[j],c[j+1]) > 0) //arr + j
{
strcpy(temp, c[j]);// only strcpy, assignment not works
strcpy(c[j], c[j + 1]);
strcpy(c[j + 1], temp);
}
}
}
}
после завершения внешнего цикла и после завершения функции я получаю эту ошибку:
Run-Time Check Failure #2 - Stack around the variable 'temp' was corrupted.
Есть идеи, почему я получаю ошибку выше?
temp
имеет размер 1, которого достаточно для хранения пустой строки и ничего больше.
Поскольку вы не указываете его явно, размер temp
берется из размера инициализатора, который равен 1. Следовательно, temp
недостаточно велик, чтобы вместить любую из ваших строк. Либо используйте temp[] = “ “;
, либо temp[5] = “”:
@JohnBode Я рекомендую "
вместо “
или ”
. :-)
@JohnBode, но почему я получаю сообщение об ошибке при завершении функции? Он отлично работает, пока выполняется во внутренних и внешних циклах.
@Michael Тебе повезло, что ты вообще получаешь ошибку. Ошибки в коде C могут проявляться самыми странными и чудесными способами.
Добро пожаловать в чудесный мир неопределенного поведения! ;-) Может вылететь, или нет, или только сейчас, или только при полнолунии, или когда твоя подружка только что ушла от тебя, или на 16-м дне рождения твоей бабушки или ...
У вас недостаточно буферного хранилища для временной переменной. Вам нужно будет знать max_length для заданных строк и выделить достаточно памяти в стеке. Если вы этого не знаете, то другой вариант - динамическое размещение в куче.
memset
бессмыслен. temp
всегда устанавливается перед использованием. Максимальная длина известна (char c[][5]
).
max_length для строк? Как?
Я исправил свой ответ на основании вашего комментария. Вы правы, что memset () в данном случае бессмысленна.
Небольшое наблюдение из кода, который вы упомянули. Во-первых, здесь
char temp[] = "";
Размер temp
слишком мал для размещения c[j]
. Сделайте его достаточно большим, чтобы он мог вместить c[j]
. Например,
char temp[5] = "";
Во-вторых, итерация внутреннего цикла for
пузырьковой сортировки некорректна. Вместо j < size - 1
используйте j < size - i-1
.
Это определение temp [] инициализирует его одним символом (байтом) 0. Когда вы копируете c [j], вы копируете все байты c [j] в память, начиная с temp. Если c [j] имеет более 1 символа, дополнительная память, не принадлежащая temp, будет перезаписана и, вероятно, это локальный стековый фрейм функции.
Компилятор проверяет это в режиме отладки и сообщает подробности - см. Подробности в Проверки ошибок во время выполнения и Размещение стека.
И если вы выделите слишком много в стеке, вы получите переполнение стека!
«Компилятор проверяет это в режиме отладки» «режим отладки? Какой режим отладки? В C никогда не полагайтесь на компилятор, выполняющий работу программиста.
Ключ / RTC - по умолчанию включен в режиме отладки. Отладка и выпуск генерируют другой код. Если вы пишете прямые проверки диапазона для вектора или указываете компилятор для этого - и то, и другое помогает.
char temp[] = "";
слишком мал для копирования. Пожалуйста, попробуйтеchar temp[5] = "";