简体   繁体   English

尝试释放时程序崩溃()

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM