Как может программа на C без указателей продолжать выдавать мне ошибку ошибки сегментации?

#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/