C 尝试释放()时程序崩溃

C 尝试释放()时程序崩溃,c,gdb,C,Gdb,试图创建一个程序,将两个字符串循环连接在一起,打印出字母表。当我等于11时,我在尝试释放(新)时出错 这是我在尝试调试时从GDB获得的结果: (gdb) 56 free(new); (gdb) info locals new = 0x804b008 "l" new_word = 0x804b038 "abcdefghijkl" buff = 108 i = 11 word = 0x804b018 "abcdefghijkl" (gdb) n *** Error in

试图创建一个程序,将两个字符串循环连接在一起,打印出字母表。当我等于11时,我在尝试释放(新)时出错

这是我在尝试调试时从GDB获得的结果:

(gdb) 
56              free(new);
(gdb) info locals
new = 0x804b008 "l"
new_word = 0x804b038 "abcdefghijkl"
buff = 108
i = 11
word = 0x804b018 "abcdefghijkl"
(gdb) n
*** Error in `/home/jharvard/Dropbox/pset6/test': invalid fastbin entry (free): 0x0804b008 ***

Program received signal SIGSEGV, Segmentation fault.
0x4408e098 in malloc_consolidate (av=av@entry=0x441d4420 <main_arena>)
    at malloc.c:4093
4093              unlink(av, nextchunk, bck, fwd);
(gdb)
56免费(新);
(gdb)本地信息
新=0x804b008“l”
新单词=0x804b038“abcdefghijkl”
buff=108
i=11
word=0x804b018“abcdefghijkl”
(gdb)n
***“/home/jharvard/Dropbox/pset6/test”中出错:fastbin条目无效(免费):0x0804b008***
程序接收信号SIGSEGV,分段故障。
malloc_合并(av)中的0x4408e098=av@entry=0x441d4420)
在malloc.c:4093
4093取消链接(av、nextchunk、bck、fwd);
char*new=malloc(sizeof(char))
分配长度为1的缓冲区。 然后,将一个字符(%c)sprintf到该缓冲区,这需要2个字节(字符和终止零),因此缓冲区溢出和内存损坏

顺便说一句,如果完全低效且基本无用,则分配非常小的缓冲区。您可能应该从头开始重新考虑您的程序。

char*new=malloc(sizeof(char))
分配长度为1的缓冲区。 然后,将一个字符(%c)sprintf到该缓冲区,这需要2个字节(字符和终止零),因此缓冲区溢出和内存损坏


顺便说一句,如果完全低效且基本无用,则分配非常小的缓冲区。您可能应该从头开始重新考虑您的程序。

C中的字符串结尾必须始终有一个空终止符(也称“\0”)。空终止符标记字符串的结尾。如果没有空终止符,许多C字符串库函数将运行到字符串末尾,如果幸运的话,将导致崩溃。如果运气不好,超过字符串末尾运行将损坏与该字符串无关的数据,导致难以找到的bug。
strlen
函数计算字符串中的字符数,但该计数不包括空终止符

char *new = malloc(sizeof(char));                      // returns a pointer to 1 byte of memory.
sprintf(new, "%c", buff);                              // writes two characters into that memory, whatever buff is, and a null terminator '\0'
*word = *new;                                          // copies the first character of 'new' into 'word', but doesn't null terminate 'word'
word = (char *) malloc(sizeof(new));                   // since new is a pointer, sizeof(new) is the size of a pointer, 4 bytes on 32-bit systems, 8 bytes on 64-bit systems
char* new_word = malloc(strlen(word) + strlen(new));   // allocates enough space for the two string but doesn't include space for the null terminator
word = (char *) realloc(word, strlen(new_word));       // again no space for the null terminator

可能还有更多,但你明白了。

C中的字符串结尾必须始终有一个空终止符(也称“\0”)。空终止符标记字符串的结尾。如果没有空终止符,许多C字符串库函数将运行到字符串末尾,如果幸运的话,将导致崩溃。如果运气不好,超过字符串末尾运行将损坏与该字符串无关的数据,导致难以找到的bug。
strlen
函数计算字符串中的字符数,但该计数不包括空终止符

char *new = malloc(sizeof(char));                      // returns a pointer to 1 byte of memory.
sprintf(new, "%c", buff);                              // writes two characters into that memory, whatever buff is, and a null terminator '\0'
*word = *new;                                          // copies the first character of 'new' into 'word', but doesn't null terminate 'word'
word = (char *) malloc(sizeof(new));                   // since new is a pointer, sizeof(new) is the size of a pointer, 4 bytes on 32-bit systems, 8 bytes on 64-bit systems
char* new_word = malloc(strlen(word) + strlen(new));   // allocates enough space for the two string but doesn't include space for the null terminator
word = (char *) realloc(word, strlen(new_word));       // again no space for the null terminator

可能还有更多,但你明白了。

看起来像堆损坏。我认为没有必要在每个循环迭代中动态分配和释放一个字符。这看起来是一个巨大的浪费时间。你在使用C++吗?C不允许循环初始声明。整个程序看起来太复杂了。@Shashwat,如果你说的是(int i=0;,在过去15年中允许在C中看起来像堆损坏。我不认为在每个循环迭代中有必要动态分配和释放一个字符。这看起来是一个巨大的浪费时间。您是否使用C++?C不允许循环初始声明。整个程序看起来过于复杂。@ashwat,如果你说的是过去15年来C语言中允许使用的
for(int i=0;
),那么,
word=(char*)malloc(sizeof(new));
sizeof new
char*
的大小。这与所指向的字符串中的字符数无关。另外,
new\u-word=malloc(strlen)(word)+strlen(new));
不考虑所需的尾部NULL。与
realloc()相同的问题
稍后。OP的代码基本上是一团糟。是的,我在mallocs中添加了+1,但仍然得到了相同的结果。很抱歉,如果代码一团糟,我对此非常陌生…@user3466332:你希望该程序打印什么?请更新你的问题。分配的内存并不是有终止零,而是通过te只是作为一种被广泛使用的字符串结尾识别的约定。此外,
word=(char*)malloc(sizeof(new));
sizeof new
char*
的大小。这与所指向的字符串中的字符数无关。此外,
new\u word=malloc(strlen(word)+strlen(new));
不考虑所需的尾随NULL。与
realloc()相同的问题
稍后。OP的代码基本上是一团糟。是的,我在mallocs中添加了+1,但仍然得到了相同的结果。很抱歉,如果代码一团糟,我对此非常陌生…@user3466332:你希望该程序打印什么?请更新你的问题。分配的内存并不是有终止零,而是通过te只是作为一种被广泛使用的字符串结尾识别的约定。
char *new = malloc(sizeof(char));                      // returns a pointer to 1 byte of memory.
sprintf(new, "%c", buff);                              // writes two characters into that memory, whatever buff is, and a null terminator '\0'
*word = *new;                                          // copies the first character of 'new' into 'word', but doesn't null terminate 'word'
word = (char *) malloc(sizeof(new));                   // since new is a pointer, sizeof(new) is the size of a pointer, 4 bytes on 32-bit systems, 8 bytes on 64-bit systems
char* new_word = malloc(strlen(word) + strlen(new));   // allocates enough space for the two string but doesn't include space for the null terminator
word = (char *) realloc(word, strlen(new_word));       // again no space for the null terminator