2016-12-06 6 views
0

Хорошо, поэтому я пытаюсь сохранить текст из файла в строке, и все работает нормально, пока я не заметил, что я неправильно перераспределял память и не должен работать.Почему это динамическое создание строки генерирует ошибку exc_bad_access после фиксированного числа?

Это моя main функции прежде, чем исправить ее:

FILE * file; 
char * quijote, thisChar; 
unsigned int writingAt = 0; 

file = fopen("quijote.txt", "r"); 
quijote = malloc(1); 

if (file != NULL) { 
    while (1) { 
     thisChar = (char)fgetc(file); 
     if (thisChar == EOF) { 
      break; 
     } else { 
      printf("strlen(quijote) = %lu; writingAt = %i\n", strlen(quijote), writingAt); 
      quijote = (char *) realloc(quijote, (sizeof(quijote) + 1)); 
      quijote[writingAt] = thisChar; 
      quijote[writingAt + 1] = '\0'; 
      writingAt++; 
     } 
    } 
} else { 
    perror("fopen"); 
} 
fclose(file); 

Он отлично работает, и правильно хранит весь файл в строке. Обратите внимание, что перераспределение памяти неверно, так как sizeof(quijote) всегда имеет такое же значение (8), поэтому теоретически он не должен работать.

Теперь, когда я исправил перераспределение, он случайно генерирует ошибку EXC_BAD_ACCESS при записиAt = 135167. Это «исправлено» main функция:

FILE * file; 
char * quijote, thisChar; 
unsigned int writingAt = 0; 

file = fopen("quijote.txt", "r"); 
quijote = malloc(1); 

if (file != NULL) { 
    while (1) { 
     thisChar = (char)fgetc(file); 
     if (thisChar == EOF) { 
      break; 
     } else { 
      printf("strlen(quijote) = %lu; writingAt = %i\n", strlen(quijote), writingAt); 
      quijote = (char *) realloc(quijote, (writingAt + 1)); 
      quijote[writingAt] = thisChar; 
      quijote[writingAt + 1] = '\0'; 
      writingAt++; 
     } 
    } 
} else { 
    perror("fopen"); 
} 
fclose(file); 

И эти последние строки программа печатает перед ошибкой:

strlen(quijote) = 135162; writingAt = 135162 
strlen(quijote) = 135163; writingAt = 135163 
strlen(quijote) = 135164; writingAt = 135164 
strlen(quijote) = 135165; writingAt = 135165 
strlen(quijote) = 135166; writingAt = 135166 
strlen(quijote) = 135167; writingAt = 135167 
Exception: EXC_BAD_ACCESS (code=1, address=0x10fc20000) 

я не понимаю, почему предыдущий код работал, и это Безразлично» t, или почему программа выдает ошибку в этом конкретном номере. Кроме того, я пытался перераспределить до размера 1, как это: quijote = (char *) realloc(quijote, 1); и по какой-то причине он также работает ...

+3

Существует * причина * почему 'fgetc()' возвращает 'int'. Таким образом, вы используете его неправильно. Кроме того, 'sizeof()'! = 'Strlen()'. – EOF

+0

@ user3121023 Хорошо, но удалите бросок. –

+0

@EOF в чем причина? Да, я знаю, что sizeof и strlen не совпадают, поэтому почему первая функция неверна ... Любая идея о том, почему она работает? – dieortin

ответ

2

Вы выделяете writingAt + 1 символов, то доступ quijote[writingAt + 1] что неопределенное поведение - это (writingAt + 2) -й символ, который больше, чем фактическое количество выделенных символов.