#c #segmentation-fault
#c #ошибка сегментации
Вопрос:
Программа, скопированная ниже, выдает мне ошибку ошибки сегментации.
Я очень смущен, почему это происходит. Я читал, что ошибки сегментации касаются только программ, использующих указатели, и я специально избавился от своих указателей, потому что раньше они выдавали мне слишком много таких ошибок.
Однако, как я уже сказал, в этой программе ее нет! Я очень раздосадован. Может кто-нибудь, пожалуйста, подсказать, как исправить эту ситуацию? Я просмотрел ее построчно 10 раз и не увидел ничего бросающегося в глаза.
int main(int argc,char *argv[]){
char engw [7] [3] = {{'S','u','n'},{'M','o','n'},{'T','u','e'},{'W','e','d'},{'T','h','u'},{'F','r','i'},{'S','a','t'}};
char engy [12] [3] = {{'J','a','n'},{'F','e','b'},{'M','a','r'},{'A','p','r'},{'M','a','y'},{'J','u','n'},{'J','u','l'},{'A','u','g'},{'S','e','p'},{'O','c','t'},{'N','o','v'},{'D','e','c'}};
/*how do I get standard input?*/
char test [3] = {0,0,0};
test[0] = getchar();
test[1] = getchar();
test[2] = getchar();
short domd = 7;
short domm = 12;
short daynum = 0;
short counter = 0;
for (short q=0; q<domd; q ){
if ((engw[q][0]==test[0])amp;amp;(engw[q][1]==test[1])amp;amp;(engw[q][2]==test[2])){
counter=q;
}
char newword [32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
short num = counter;
FILE * wd;
wd = fopen("$1", "r");
short w=0;
while(((fgetc(wd)) != EOF)amp;amp; (num>=1)) {
if ((fgetc(wd)) == ' ') {
num--;
}
if (num == 1) {
newword [w] = (( fgetc(wd)));
w ;
}
fclose(wd);
short newstr=strlen(newword);
for (short h=0; h<newstr; h ){
char x=newword[h];
printf ("%c", x);
}
}
char space = getchar();
printf ("%c", space);
getchar(); /* for the space between the month and the day at hand */
test[0] = getchar();
test[1] = getchar();
test[2] = getchar();
for (short m=0; q<domm; m ){
if ((engy[q][0]==test[0])amp;amp;(engy[q][1]==test[1])amp;amp;(engy[q][2]==test[2])){
counter=m;
}
char newwordo [32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
short numo = counter;
FILE * wd;
wd = fopen("$1", "r");
short u=0;
while(((fgetc(wd) != 'n') amp;amp; (fgetc(wd)!= EOF)));
while(((fgetc(wd)) != EOF)amp;amp; (num>=1)) {
if ((fgetc(wd) == ' ')) {
numo--;
}
if (numo == 1) {
newwordo [u] = ((fgetc(wd)));
u ;
}
fclose(wd);
short newstro=strlen(newwordo);
for (short k=0; k<newstro; k ){
char x=newwordo[k];
printf ("%c", x);
}
}
}
}
}
Комментарии:
1. Таким образом, по вашей логике программа без явного использования указателя не может завершиться сбоем.
2. Запускайте конец массива в недопустимую память.
3. Массивы связаны с указателями. И у вас есть хотя бы один указатель, который вы не проверяете, есть ли он
NULL
.FILE*
Возвращаемоеfopen
.4. В любом случае, способ устранить подобные сбои — использовать отладчик. Если вы запустите отладочную сборку в отладчике, вы можете перехватить сбой в действии и определить, где в вашем коде это происходит. Вы также сможете проверить переменные и их значения, чтобы убедиться, что с ними все в порядке.
5. О, и почему вы закрываете файл в середине циклов? Это определенно приведет к неопределенному поведению при следующей попытке чтения из файла.
Ответ №1:
Необязательно, чтобы только использование указателей приводило к ошибкам сегментации. Ошибки сегментации возникают, когда вы пытаетесь получить доступ к любому адресу памяти, к которому вам не разрешено. Указатели (которые включают указатели на файлы, которые вы, кстати, используете) по сути являются адресами.
Скорее всего, fopen потерпел неудачу и вернул нулевой указатель. И это адрес, к которому вы определенно не можете получить доступ. Поэтому всегда желательно проверить, является ли (wd == null), прежде чем начинать ее использовать.
В качестве альтернативы, если вам интересно, где происходят сбои в сегментации, GDB — отличный инструмент, который позволит вам просмотреть обратную трассировку и точно определить, на какой строке произошел сбой вашей программы.
Вот руководство по использованию GDB: https://www.cs.cmu.edu / ~ gilpin/tutorial/