[英]Program crashing when trying to free()
Trying to create a program that loops connecting two strings together printing out the alphabet. 尝试创建一个程序,该程序循环将两个字符串连接在一起,以打印出字母。 When i gets to equal 11, I get an error when trying to free(new).
当我等于11时,尝试释放(新)时出现错误。
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char* word = NULL;
for(int i = 0; i < 25; i++)
{
int buff = 'a' + i;
// creates first string
if (i == 0)
{
char* new = malloc(sizeof(char) + 1);
if (new == NULL)
{
printf("malloc failed");
return 1;
}
sprintf(new, "%c", buff);
word = (char *) malloc(sizeof(new));
if (word == NULL)
{
printf("malloc failed");
return 1;
}
*word = *new;
free(new);
}
// adds string word to string new
else
{
char* new = malloc(sizeof(char) + 1);
if (new == NULL)
{
printf("malloc failed");
return 1;
}
sprintf(new, "%c", buff);
char* new_word = malloc(strlen(word) + strlen(new) + 1);
if (new_word == NULL)
{
printf("malloc failed");
return 1;
}
// Copies combines word and new into new_word
strcpy(new_word, word);
strcat(new_word, new);
// Resizes memory for word and prints new_word into word
word = (char *) realloc(word, strlen(new_word));
sprintf(word, "%s", new_word);
// Frees looped vars
free(new);
free(new_word);
}
printf("%s\n", word);
}
}
This is the results I get: 这是我得到的结果:
a
ab
abc
abcd
abcde
abcdef
abcdefg
abcdefgh
abcdefghi
abcdefghij
abcdefghijk
*** Error in `./test': free(): invalid pointer: 0x08cac028 ***
this is what I get from GDB when trying to debug: 这是我在尝试调试时从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);
char* new = malloc(sizeof(char))
allocates a buffer of length 1. Then you sprintf a char (%c) to that buffer and that takes 2 bytes (the char and the terminating zero) hence a buffer overflow and memory corruption. char* new = malloc(sizeof(char))
分配一个长度为1的缓冲区。然后将一个char(%c)sprintf分配到该缓冲区,该缓冲区占用2个字节(char和终止的零),因此缓冲区溢出和内存损坏。
BTW allocating very small buffers if totally inefficient and basically useless. 如果完全无效并且基本上没有用,BTW分配非常小的缓冲区。 You should probably rethink your program from the ground up.
您可能应该从头开始重新考虑您的程序。
Strings in C must always have a null terminator (aka '\\0') at the end. C中的字符串末尾必须始终有一个空终止符(aka'\\ 0')。 The null terminator marks the end of the string.
空终止符标记字符串的结尾。 Without the null terminator, many of the C string library functions will run past the end of the string, causing a crash if you're lucky.
如果没有空终止符,那么许多C字符串库函数都将在字符串末尾运行,如果幸运的话,会导致崩溃。 If you're unlucky, running past the end of a string will corrupt data unrelated to the string, causing bugs that are excruciatingly difficult to find.
如果您不走运,超过字符串的末尾将破坏与字符串无关的数据,从而导致难以发现的错误。 The
strlen
function counts the number of characters in a string, but that count does not include the null terminator. 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
There might be more, but you get the idea. 可能还有更多,但是您明白了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.