【问题标题】:Why does valgrind talk about 'Mismatched free()'为什么 valgrind 谈论“不匹配的免费()”
【发布时间】:2020-07-23 19:12:52
【问题描述】:

我正在尝试构建一个树型结构,它将存储 IMAP 命令的令牌。我正在尝试向它们添加字符串,并释放它们。但是 valgrind 抱怨,我不知道为什么。

#include <iostream>
#include <algorithm>
#include <vector>

#include <string.h>

typedef enum : uint8_t
{
    TT_STRING,
    TT_INT32,
    TT_INT64,
    TT_CHAR,
    TT_PAIR
} TokenType;

typedef struct
{
    int32_t p_From;
    int32_t p_To;
} Pair;

struct Token
{
    union {
        char *t_String;
        int32_t t_Int32;
        int64_t t_Int64;
        char t_Char;
        Pair t_Pair;
    };
    TokenType t_Type;
    std::vector<Token> t_Children;
};

typedef struct Token Token;

void _token_free(Token &token)
{
    if (token.t_Type == TT_STRING)
    {
        delete token.t_String;
    }

    for_each(token.t_Children.begin(), token.t_Children.end(), [=](Token &t){
        _token_free(t);
    });
}

Token _token_str_new(const std::string &str)
{
    Token token;
    token.t_Type = TT_STRING;
    token.t_String = new char[str.size() + 1];
    memcpy(reinterpret_cast<void *>(token.t_String), str.c_str(), str.size() + 1);
    return token;
}

int main() {
    Token token;

    token.t_Int64 = 123;
    token.t_Type = TT_INT64;
    token.t_Children = {
            _token_str_new("Hello World")
    };

    _token_free(token);

    return 0;
}

Valgrind 说:

Mismatched free() / delete / delete []
_token_free(Token&)
_token_free(Token&)::{lambda(Token&)#1}::operator()(Token&) const
_token_free(Token&)::{lambda(Token&)#1} std::for_each<__gnu_cxx::__normal_iterator, _token_free(Token&)::{lambda(Token&)#1}>(__gnu_cxx::__normal_iterator<Token*, std::vector>, _token_free(Token&)::{lambda(Token&)#1}, _token_free(Token&)::{lambda(Token&)#1})
_token_free(Token&)
main
Address 0x4dc0c80 is 0 bytes inside a block of size 12 alloc'd
operator new[](unsigned long)
_token_str_new(std::__cxx11::basic_string<char, std::char_traits, std::allocator> const&)
main

【问题讨论】:

  • t_String 被分配给new[],但被delete 删除。您需要使用delete[] 表单。 (或者更好的是,使用smart pointers 和/或standard containers,这样您就不需要手动处理内存管理。)
  • 无关:C++ 从 C 中学到了很多东西。它学到的东西之一是 typedef 结构技巧,即使每个人都知道,也不必一直键入 structenum该死的,它是structenum。 C++ 将诀窍融入其中。struct Pair { members... }; 是您使用Pair 所需要做的一切。
  • 当 SO 告诉你做更多的解释和更少的代码转储,而不是给我们 Lorem Ipsum,请听从建议...
  • 另外,您的 Token, 类没有复制构造函数,但 token.t_Children = { 将复制它,可能导致双重删除。 What is the Rule of 3?What is the Rule of Zero?

标签: c++


【解决方案1】:

当您在_token_str_new 中分配给token.t_String 时,您使用new[]_token_free 使用 delete,导致不匹配。

您需要在_token_free 中使用delete [] token.t_String

【讨论】:

  • 谢谢! Lmao 这是我犯的一个愚蠢的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
相关资源
最近更新 更多