在 c 中出现 "corrupted size vs. prev_size" 错误
getting a "corrupted size vs. prev_size" error in c
我需要制作一个函数来接收无限制的输入,只有在到达 EOF 时才会停止读取。我必须使用 realloc
函数。
这是我当前的代码:
#include <stdio.h>
#include <stdlib.h>
char *getInput() {
char *currentString, currentChar;
int currentSize;
currentString = (char *)malloc(sizeof(char) * 2);
currentSize = 0;
currentChar = 0;
if (currentString != NULL) {
while (currentChar != EOF) {
currentChar = getchar();
currentString[currentSize++] = currentChar;
currentString = realloc(currentString, currentSize);
}
}
return currentString;
}
int main(int argc, char *argv[]) {
char *userInput;
userInput = getInput();
printf("\n string is: %s", userInput);
return 0;
}
代码正常工作,除了每当我输入一个超过 13 个字符的字符串时,我收到以下错误(文件名是 list_ab):
*** Error in `./list_ab': corrupted size vs. prev_size: 0x08ff6010 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x67377)[0xb75a7377]
/lib/i386-linux-gnu/libc.so.6(+0x6d2f7)[0xb75ad2f7]
/lib/i386-linux-gnu/libc.so.6(+0x7049e)[0xb75b049e]
/lib/i386-linux-gnu/libc.so.6(realloc+0x10e)[0xb75b162e]
./list_ab[0x804851d]
./list_ab[0x8048544]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf7)[0xb7558637]
./list_ab[0x80483d1]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:02 359220 /home/user/Desktop/Maman12/list_ab
08049000-0804a000 r--p 00000000 08:02 359220 /home/user/Desktop/Maman12/list_ab
0804a000-0804b000 rw-p 00001000 08:02 359220 /home/user/Desktop/Maman12/list_ab
08ff6000-09017000 rw-p 00000000 00:00 0 [heap]
b7400000-b7421000 rw-p 00000000 00:00 0
b7421000-b7500000 ---p 00000000 00:00 0
b750d000-b7529000 r-xp 00000000 08:02 931606 /lib/i386-linux-gnu/libgcc_s.so.1
b7529000-b752a000 rw-p 0001b000 08:02 931606 /lib/i386-linux-gnu/libgcc_s.so.1
b7540000-b76f0000 r-xp 00000000 08:02 933356 /lib/i386-linux-gnu/libc-2.23.so
b76f0000-b76f2000 r--p 001af000 08:02 933356 /lib/i386-linux-gnu/libc-2.23.so
b76f2000-b76f3000 rw-p 001b1000 08:02 933356 /lib/i386-linux-gnu/libc-2.23.so
b76f3000-b76f6000 rw-p 00000000 00:00 0
b770b000-b770e000 rw-p 00000000 00:00 0
b770e000-b7710000 r--p 00000000 00:00 0 [vvar]
b7710000-b7711000 r-xp 00000000 00:00 0 [vdso]
b7711000-b7733000 r-xp 00000000 08:02 931813 /lib/i386-linux-gnu/ld-2.23.so
b7733000-b7734000 rw-p 00000000 00:00 0
b7734000-b7735000 r--p 00022000 08:02 931813 /lib/i386-linux-gnu/ld-2.23.so
b7735000-b7736000 rw-p 00023000 08:02 931813 /lib/i386-linux-gnu/ld-2.23.so
bfd35000-bfd56000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
经过大量谷歌搜索后,我发现每当我尝试写入无法访问的位置时都会发生错误,但是 none 提到的修复有效。
我该如何解决这个问题?
如果它对 运行 on linux vm.
有帮助
总结来自评论的所有输入:
argc
& argv
都没有用,那为什么要声明呢?
getchar()
returns a int
to cover EOF
通常所有位都设置为 1
变成 -1
2 的补码.所以,currentChar
需要是 int
.
- 字符串不是空终止的,当用作 nul-terminated 字符串时可能会导致缓冲区溢出。
free()
使用后分配的内存。
- 为
str
中的 nul
('\0') 创建 space & 检查 realloc()
的 return 值。
- 变量名不要大方,阅读需要时间
代码简化:
#include <stdio.h>
#include <stdlib.h>
char* getInput() {
char *str = malloc (sizeof (char) * 2);
if (!str) {
perror ("malloc"); return NULL;
}
int ich;
int slen = 0;
while ((ich = getchar()) != EOF) {
str[slen++] = ich;
char* str2 = realloc (str, slen + 1);
if (!str2) {
perror ("realloc"); free (str); return NULL;
}
str = str2;
}
str[slen] = '[=10=]';
return str;
}
int main() {
char *userInput = getInput();
if (userInput) {
printf ("String is: %s\n", userInput);
free (userInput);
}
return 0;
}
代码中存在多个问题:
currentChar
的类型应该是 int
以容纳 getchar()
返回的所有可能值,即所有 unsigned char
类型的值(0
到 255
对于 8 位字节)和特殊的负值 EOF
(通常定义为 (-1)
)。
第一次测试 currentChar != EOF
时,变量 currentChar
未初始化,导致未定义的行为。
你应该在从标准输入中读取字节后并在将其附加到数组之前测试 EOF
。
你在设置下一个字符后重新分配数组:除了第一次,你写的字节超出分配对象的末尾:你应该在 附加字节之前重新分配数组 。
你没有为空终止符分配足够的space,你没有设置它。
你不检查 malloc()
也不检查 realloc()
失败。
你没有释放 main()
中的字符串。
一次重新分配一个字节是低效的。
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
char *getInput(void) {
size_t len = 0;
size_t size = 8;
char *str = malloc(size);
char *newstr;
int c;
if (str == NULL) {
fprintf(stderr, "malloc failure for %zu bytes\n", size);
return NULL;
}
while ((c = getchar()) != EOF) {
if (len + 2 > size) {
/* increase the allocated block size by 50% */
size += size / 2;
newstr = realloc(str, size);
if (newstr == NULL) {
free(str);
fprintf(stderr, "realloc failure for %zu bytes\n", size);
return NULL;
}
str = newstr;
}
str[len++] = c;
}
/* try and reduce the size of the allocated string */
newstr = realloc(str, len + 1);
if (newstr != NULL)
str = newstr;
/* set the null terminator */
str[len] = '[=10=]';
return str;
}
int main() {
char *userInput = getInput();
if (userInput) {
printf("string is: %s\n", userInput);
free(userInput);
}
return 0;
}
我需要制作一个函数来接收无限制的输入,只有在到达 EOF 时才会停止读取。我必须使用 realloc
函数。
这是我当前的代码:
#include <stdio.h>
#include <stdlib.h>
char *getInput() {
char *currentString, currentChar;
int currentSize;
currentString = (char *)malloc(sizeof(char) * 2);
currentSize = 0;
currentChar = 0;
if (currentString != NULL) {
while (currentChar != EOF) {
currentChar = getchar();
currentString[currentSize++] = currentChar;
currentString = realloc(currentString, currentSize);
}
}
return currentString;
}
int main(int argc, char *argv[]) {
char *userInput;
userInput = getInput();
printf("\n string is: %s", userInput);
return 0;
}
代码正常工作,除了每当我输入一个超过 13 个字符的字符串时,我收到以下错误(文件名是 list_ab):
*** Error in `./list_ab': corrupted size vs. prev_size: 0x08ff6010 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x67377)[0xb75a7377]
/lib/i386-linux-gnu/libc.so.6(+0x6d2f7)[0xb75ad2f7]
/lib/i386-linux-gnu/libc.so.6(+0x7049e)[0xb75b049e]
/lib/i386-linux-gnu/libc.so.6(realloc+0x10e)[0xb75b162e]
./list_ab[0x804851d]
./list_ab[0x8048544]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf7)[0xb7558637]
./list_ab[0x80483d1]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:02 359220 /home/user/Desktop/Maman12/list_ab
08049000-0804a000 r--p 00000000 08:02 359220 /home/user/Desktop/Maman12/list_ab
0804a000-0804b000 rw-p 00001000 08:02 359220 /home/user/Desktop/Maman12/list_ab
08ff6000-09017000 rw-p 00000000 00:00 0 [heap]
b7400000-b7421000 rw-p 00000000 00:00 0
b7421000-b7500000 ---p 00000000 00:00 0
b750d000-b7529000 r-xp 00000000 08:02 931606 /lib/i386-linux-gnu/libgcc_s.so.1
b7529000-b752a000 rw-p 0001b000 08:02 931606 /lib/i386-linux-gnu/libgcc_s.so.1
b7540000-b76f0000 r-xp 00000000 08:02 933356 /lib/i386-linux-gnu/libc-2.23.so
b76f0000-b76f2000 r--p 001af000 08:02 933356 /lib/i386-linux-gnu/libc-2.23.so
b76f2000-b76f3000 rw-p 001b1000 08:02 933356 /lib/i386-linux-gnu/libc-2.23.so
b76f3000-b76f6000 rw-p 00000000 00:00 0
b770b000-b770e000 rw-p 00000000 00:00 0
b770e000-b7710000 r--p 00000000 00:00 0 [vvar]
b7710000-b7711000 r-xp 00000000 00:00 0 [vdso]
b7711000-b7733000 r-xp 00000000 08:02 931813 /lib/i386-linux-gnu/ld-2.23.so
b7733000-b7734000 rw-p 00000000 00:00 0
b7734000-b7735000 r--p 00022000 08:02 931813 /lib/i386-linux-gnu/ld-2.23.so
b7735000-b7736000 rw-p 00023000 08:02 931813 /lib/i386-linux-gnu/ld-2.23.so
bfd35000-bfd56000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
经过大量谷歌搜索后,我发现每当我尝试写入无法访问的位置时都会发生错误,但是 none 提到的修复有效。 我该如何解决这个问题? 如果它对 运行 on linux vm.
有帮助总结来自评论的所有输入:
argc
&argv
都没有用,那为什么要声明呢?getchar()
returns aint
to coverEOF
通常所有位都设置为1
变成-1
2 的补码.所以,currentChar
需要是int
.- 字符串不是空终止的,当用作 nul-terminated 字符串时可能会导致缓冲区溢出。
free()
使用后分配的内存。- 为
str
中的nul
('\0') 创建 space & 检查realloc()
的 return 值。 - 变量名不要大方,阅读需要时间
代码简化:
#include <stdio.h>
#include <stdlib.h>
char* getInput() {
char *str = malloc (sizeof (char) * 2);
if (!str) {
perror ("malloc"); return NULL;
}
int ich;
int slen = 0;
while ((ich = getchar()) != EOF) {
str[slen++] = ich;
char* str2 = realloc (str, slen + 1);
if (!str2) {
perror ("realloc"); free (str); return NULL;
}
str = str2;
}
str[slen] = '[=10=]';
return str;
}
int main() {
char *userInput = getInput();
if (userInput) {
printf ("String is: %s\n", userInput);
free (userInput);
}
return 0;
}
代码中存在多个问题:
currentChar
的类型应该是int
以容纳getchar()
返回的所有可能值,即所有unsigned char
类型的值(0
到255
对于 8 位字节)和特殊的负值EOF
(通常定义为(-1)
)。第一次测试
currentChar != EOF
时,变量currentChar
未初始化,导致未定义的行为。你应该在从标准输入中读取字节后并在将其附加到数组之前测试
EOF
。你在设置下一个字符后重新分配数组:除了第一次,你写的字节超出分配对象的末尾:你应该在 附加字节之前重新分配数组 。
你没有为空终止符分配足够的space,你没有设置它。
你不检查
malloc()
也不检查realloc()
失败。你没有释放
main()
中的字符串。一次重新分配一个字节是低效的。
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
char *getInput(void) {
size_t len = 0;
size_t size = 8;
char *str = malloc(size);
char *newstr;
int c;
if (str == NULL) {
fprintf(stderr, "malloc failure for %zu bytes\n", size);
return NULL;
}
while ((c = getchar()) != EOF) {
if (len + 2 > size) {
/* increase the allocated block size by 50% */
size += size / 2;
newstr = realloc(str, size);
if (newstr == NULL) {
free(str);
fprintf(stderr, "realloc failure for %zu bytes\n", size);
return NULL;
}
str = newstr;
}
str[len++] = c;
}
/* try and reduce the size of the allocated string */
newstr = realloc(str, len + 1);
if (newstr != NULL)
str = newstr;
/* set the null terminator */
str[len] = '[=10=]';
return str;
}
int main() {
char *userInput = getInput();
if (userInput) {
printf("string is: %s\n", userInput);
free(userInput);
}
return 0;
}