为什么这个动态字符串创建会在固定数字后抛出 exc_bad_access 错误?
Why does this dynamic string creation throw exc_bad_access error after a fixed number?
好的,所以我正在尝试将文件中的文本存储在一个字符串中,并且一切正常,直到我发现我没有正确地重新分配内存,它不应该工作。
这是我的 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] = '[=11=]';
writingAt++;
}
}
} else {
perror("fopen");
}
fclose(file);
它工作得很好,并且正确地将所有文件存储在字符串中。请注意,内存重新分配是不正确的,因为 sizeof(quijote)
始终具有相同的值 (8),因此理论上它不应该工作。
现在,当我更正重新分配时,它在 writingAt=135167 时随机抛出 EXC_BAD_ACCESS 错误。这是 "corrected" 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] = '[=12=]';
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)
我不明白为什么以前的代码可以工作而这个不行,或者为什么程序会在那个特定的数字中抛出错误。另外,我试过像这样重新分配到大小 1:quijote = (char *) realloc(quijote, 1);
并且出于某种原因它也有效...
您分配 writingAt + 1
个字符,然后访问 quijote[writingAt + 1]
,这是未定义的行为 - 它是第 (writingAt + 2) 个字符,比实际分配的字符数多一个。
好的,所以我正在尝试将文件中的文本存储在一个字符串中,并且一切正常,直到我发现我没有正确地重新分配内存,它不应该工作。
这是我的 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] = '[=11=]';
writingAt++;
}
}
} else {
perror("fopen");
}
fclose(file);
它工作得很好,并且正确地将所有文件存储在字符串中。请注意,内存重新分配是不正确的,因为 sizeof(quijote)
始终具有相同的值 (8),因此理论上它不应该工作。
现在,当我更正重新分配时,它在 writingAt=135167 时随机抛出 EXC_BAD_ACCESS 错误。这是 "corrected" 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] = '[=12=]';
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)
我不明白为什么以前的代码可以工作而这个不行,或者为什么程序会在那个特定的数字中抛出错误。另外,我试过像这样重新分配到大小 1:quijote = (char *) realloc(quijote, 1);
并且出于某种原因它也有效...
您分配 writingAt + 1
个字符,然后访问 quijote[writingAt + 1]
,这是未定义的行为 - 它是第 (writingAt + 2) 个字符,比实际分配的字符数多一个。