附加到字符串时C中的内存泄漏

问题描述 投票:0回答:1

Valgrind说存在内存泄漏,但我无法弄清楚它是什么。我尝试在追加函数中放置free,在main的末尾释放字符串,它仍然抱怨。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void append(char* string, char c)
{
    int stringlength = strlen(string);
    char* tmp = realloc(string, sizeof(char) * (stringlength + sizeof(char) + sizeof(char)));
    if(tmp == NULL)
    {
        free(tmp);
        free(string);
        printf("Error appending character\n");
        exit(1);
    }

    string = tmp;
    string[stringlength] = c;
    string[stringlength+1] = '\0';
}

int main()
{
    char* string = malloc(sizeof(char));
    string[0] = '\0';

    printf("string before appending: %s\n", string);
    append(string, 'c');
    printf("string after appending: %s\n", string);
    free(string);
    return 0;
}

这是Valgrind的输出:https://pastebin.com/dtXFm5YC(它在Pastebin中,所以Stack Overflow实际上让我发布这个问题

c memory-leaks c-strings
1个回答
1
投票

您的主要问题不是内存泄漏,而是无效访问:

Invalid read of size 1
    ...
Address 0x49d0028 is 0 bytes inside a block of size 1 free'd

并且免费无效:

Invalid free() / delete / delete[] / realloc()
...
Address 0x49d0028 is 0 bytes inside a block of size 1 free'd

因为他们有不确定的行为

  • 当你做char* tmp = realloc(string, sizeof(char) * (stringlength + sizeof(char) + sizeof(char)));释放来自main的字符串时,所以当你在main中打印它时你可以访问一个释放的块。请注意,释放块的事实realloc不是强制性的
  • 因为你没有释放由realloc新分配的tmp追加你创建你的内存泄漏
  • 然后你再次释放已经被realloc释放的字符串

sizeof(char) * (stringlength + sizeof(char) + sizeof(char))也很奇怪,你有改变sizeof(char)是定义1,可以只是stringlength + 2

你想要那个 :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void append(char ** string, char c)
{
   size_t stringlength = strlen(*string);

  *string = realloc(*string, stringlength + 2);

  if (*string == NULL)
  {
     fprintf(stderr, "cannot allocate memory\n");
     exit(1);
  }

  (*string)[stringlength] = c;
  (*string)[stringlength+1] = '\0';
}

int main()
{
    char* string = malloc(1);

    string[0] = '\0';

    printf("string before appending: '%s'\n", string);
    append(&string, 'c');
    printf("string after appending: '%s'\n", string);
    free(string);
    return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra m.c
pi@raspberrypi:/tmp $ valgrind ./a.out
==17097== Memcheck, a memory error detector
==17097== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17097== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17097== Command: ./a.out
==17097== 
string before appending: ''
string after appending: 'c'
==17097== 
==17097== HEAP SUMMARY:
==17097==     in use at exit: 0 bytes in 0 blocks
==17097==   total heap usage: 3 allocs, 3 frees, 1,027 bytes allocated
==17097== 
==17097== All heap blocks were freed -- no leaks are possible
==17097== 
==17097== For counts of detected and suppressed errors, rerun with: -v
==17097== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
© www.soinside.com 2019 - 2024. All rights reserved.