exc_bad_access в программе C

Хорошо, я знаю, что здесь есть еще один вопрос о «exc_bad_access», но, похоже, он касается разработки Objective-C и iPhone, в то время как у меня только обычный C. Я новичок в C и почти закончил свою первую программу до этого ошибка обнаружилась. Я пытаюсь понять это уже пару дней и схожу с ума. Любая помощь приветствуется. глючная функция:

void edit (int i){
    char* z;
    char* y;
    char compare1[] = "on bobbin\b\b\b\b";
    char compare2[] = "not on bobbin";
    char compare3[] = "have\b\b\b\b\b\b";
    char compare4[] = "don't have";
    char wrapedit[] = "wrapped";
    char haveedit[] = "have";
    char editing[9];

    FILE *wrappedlist = fopen("../../wrapped", "r+");
    FILE *havelist = fopen("../../havelist", "r+");

    fseek(wrappedlist, i*14, SEEK_SET);
    fseek(havelist, i*11, SEEK_SET);

    printf("Edit? (y=yes, n=no)");
    fgets(z, 2, stdin);

    if ((*z=='y') && (strncmp(haveslist[i], compare4, (size_t)1) == 0)) {
        printf("Switch \"don't have\" to \"have\"? (y=yes, n=no)");
        fgets(y, 2, stdin);

        if (*y=='y') {
            fputs(compare3, havelist);
            fclose(wrappedlist);
            fclose(havelist);
            return;
        }
        else if(*y=='n'){
            fclose(wrappedlist);
            fclose(havelist);
            return;
        }
        printf("Invalid input.");
        return;
    }

    else if ((*z=='y') && (strncmp(haveslist[i], compare3, (size_t)1) == 0)) {
        fpurge(stdout);
        printf("Edit \"wrapped\" or \"have\"?");
        fpurge(stdin);
        fgets(editing, 9, stdin);

        len = strlen(editing);
        editing[len-1]='\0';

        if (strcmp(editing, wrapedit)==0) {

        if (strncmp(wrapped[i], compare1, (size_t)1)==0) {

            printf("Switch \"on bobbin\" to \"not on bobbin\"? (y=yes, n=no)");
            fgets(y, 2, stdin);
            if (*y=='y') {

                fputs(compare2, wrappedlist);
                fclose(wrappedlist);
                fclose(havelist);
                return;
            }
            else if(*y=='n'){
                fclose(wrappedlist);
                fclose(havelist);
                return;
            }
        }
            else if(strncmp(wrapped[i], compare2, (size_t)1)==0){

                fpurge(stdout);
                printf("Switch \"not on bobbin\" to \"on bobbin\"? (y=yes, n=no)");
                fgets(y, 2, stdin);
                if (*y=='y') {

                    fwrite(compare1, (size_t)strlen(compare1), 1, wrappedlist);
                    fclose(wrappedlist);
                    fclose(havelist);
                    return;
                }
                else if(*y=='n'){
                    fclose(wrappedlist);
                    fclose(havelist);
                    return;
        }
                fpurge(stdout);
                printf("Invalid input.");
        }
            fpurge(stdout);
            printf("You don't want to edit wrapped apparently.");
            fclose(wrappedlist);
            fclose(havelist);
            return;
        }
        else if(strcmp(editing, haveedit)==0){

            if (strncmp(haveslist[i], compare3, 1) == 0){

                printf("Switch \"have\" to \"don't have\"? (y=yes, n=no)");
                fgets(y, 2, stdin);
                if (*y=='y') {
                    fputs(compare4, havelist);
                    fclose(wrappedlist);
                    fclose(havelist);
                    return;
                }
                else if(*y=='n'){
                    fclose(wrappedlist);
                    fclose(havelist);
                    return;
                }
                printf("Invalid input.");
            }
            else if(strncmp(haveslist[i], compare4, 1)==0){

                printf("Switch \"don't have\" to \"have\"? (y=yes, n=no)");
                fgets(y, 2, stdin);
                if (*y=='y') {
                    fputs(compare3, havelist);
                    fclose(wrappedlist);
                    fclose(havelist);
                    return;
                }
                else if(*y=='n'){
                    fclose(wrappedlist);
                    fclose(havelist);
                    return;             
            }
        }
            printf("Invalid input.");
        }
            printf("Not editing.");

        fclose(wrappedlist);
        fclose(havelist);

        return;
    }
    else if(*z=='n'){
        fclose(wrappedlist);
        fclose(havelist);
        return;
    }

    printf("Invalid entry");
    fclose(havelist);
    fclose(wrappedlist);
    return;
}

Я могу ввести символ в fgets после «Изменить?» подсказка, но затем я получаю ошибку exc_bad_access. Пожалуйста, помогите, спасибо.код:


person Andrew    schedule 01.08.2010    source источник
comment
Пожалуйста, пожалуйста, пожалуйста, не присылайте полный код. Мы не хотим читать все это. Если бы вы могли сузить проблему и отправить только соответствующий код, мы могли бы лучше помочь вам.   -  person zneak    schedule 01.08.2010
comment
А еще лучше пришлите полный код, но сообщите нам, какие строки являются важными. Иногда просмотр полного кода также может помочь разобраться.   -  person Billy ONeal    schedule 01.08.2010


Ответы (2)


Это происходит потому, что ваши указатели не указывают на память.

char* z; // pointer points nowhere
/* snip */
fgets(z, 2, stdin); // writing to pointer that points nowhere: boom!

Это пытается поместить в z два следующих символа из stdin. Однако z указывает на бесполезность. Вам нужно, чтобы он указывал на существующую память: одного объявления указателя недостаточно, чтобы получить память рядом с ним.

Вероятно, вам нужен буфер из 2 символов:

char z[2];

С этим кодом z будет указателем на достаточно памяти для 2 символов. (В C массив может быть передан везде, где ожидается указатель.)

Я не слишком углублялся в ваш код, но у вас будет такая же проблема для y.

person zneak    schedule 01.08.2010

Вы не выделили памяти для z или y и они остались неинициализированными, поэтому fgets пишет по случайным адресам.

person kperryua    schedule 01.08.2010