C - Ошибка сегментации в strcpy()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *vStrs[] = {"Max", "Moritz", "Bolte", "Hans Huckebein", "Helene", "Antonius", "Boeck", "Maecke", "Lempel", "Schlich"};
int main()
{
int num = sizeof(vStrs) / sizeof(vStrs[0]);
int len = sizeof(vStrs[0]);
char exchnge[len];
char vBuf[128];
char *ndata;
int i, j;
for(i=0; i<num-1; i++)
{
for(j=i+1; j<num; j++)
{
if(strcmp(vStrs[j], vStrs[i]) < 0)
{
strcpy(exchnge, vStrs[j]);
strcpy(vStrs[j], vStrs[i]);
strcpy(vStrs[i], exchnge);
}
}
}
for(i=0; i<num; i++)
printf("%s\n", vStrs[i]);
return 0;
}
Привет ребят,
Кто-нибудь знает, почему я получаю ошибку сегментации на линии strcpy(vStrs[j], vStrs[i]);
?
У меня есть массив строк и хочу его отсортировать. Но я получаю ошибку сегментации. Функция strcpy() выше, которая работает. Что случилось?
Наверное, это очевидно, но я не понимаю.
Спасибо!
2 ответа
С strcpy(vStrs[j], vStrs[i])
вы копируете содержимое строкового литерала в другой строковый литерал. Это так же, как если бы вы написали strcpy("Max","Moritz")
, но строковые литералы не должны быть изменены (его неопределенное поведение).
В любом случае, цель вашей программы - обмен указателями на содержимое, а не на содержание как таковое. Так что если вы измените программу следующим образом, все должно быть в порядке:
char *vStrs[] = {"Max", "Moritz", "Bolte", "Hans Huckebein", "Helene", "Antonius", "Boeck", "Maecke", "Lempel", "Schlich"};
int main()
{
int num = sizeof(vStrs) / sizeof(vStrs[0]);
for(int i=0; i<num-1; i++)
{
for(int j=i+1; j<num; j++)
{
if(strcmp(vStrs[j], vStrs[i]) < 0)
{
char *exchnge = vStrs[j];
vStrs[j] = vStrs[i];
vStrs[i] =exchnge;
}
}
}
for(int i=0; i<num; i++)
printf("%s\n", vStrs[i]);
return 0;
}
... потому что вы не запускали свой компилятор в самом строгом из возможных режимов проверки ошибок.
Некоторые люди считают, что -Wall
означает "все предупреждения". Это не так. Даже не -Wall -Wextra
даже приближается к "строжайшему из возможных режимов проверки ошибок". Я бы начал с -Wall -Wextra -pedantic -Wmissing-include-dirs -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wlogical-op -Wmissing-declarations -Wredundant-decls -Wshadow -Wno-system-headers -Wno-deprecated -Wunused-variable -Wunused-parameter -Wunused-function -Wunused
, а затем обратитесь к руководству, чтобы узнать, может ли ваш компилятор сделать больше для вас.
Адаптируйте этот последний абзац к выбранному вами компилятору, если вы не используете GCC. Компилятор - ваш друг, дайте ему любую возможность, чтобы вы не допустили ошибок.
С этими опциями вы получите следующее предупреждение:
предупреждение: инициализация отбрасывает спецификатор const из целевого типа указателя [-Wdiscarded-qualifiers]
Потому что это то, что происходит: "Max"
имеет тип char *
что касается стандарта языка, но - как строковый литерал - указанная память не записывается. Вот почему ваш strcpy()
segfaults на вашей машине. С -Wwrite-strings
вы указываете компилятору вместо этого делать строковые литералы char const *
(как и при использовании C++), позволяя компилятору генерировать предупреждение, когда вы игнорируете не-записываемый характер литерала.
Предупреждения компилятора. Не выходи из дома без них.