malloc、struct、std::string 和 free 可能存在内存泄漏

发布于 2024-12-07 06:41:38 字数 662 浏览 1 评论 0原文

我遇到如下情况,我不确定结构体的 std::string 元素是否泄漏内存,或者这是否可以。当调用 free(v) 时,这两个 std::string 分配的内存是否被删除?

struct MyData
{
    std::string s1;
    std::string s2;
};

void* v = malloc(sizeof(MyData));

……

MyData* d = static_cast<MyData*>(v);
d->s1 = "asdf";
d->s2 = "1234";

free(v);

漏不漏

我使用 void 指针是因为我有另一个高级结构,它由枚举和 void 指针组成。根据枚举变量的值,void* 将指向不同的数据结构。

示例:

枚举字段有 EnumValue01 => void-pointer 将指向 malloc'd MyData01 struct

enum-field has EnumValue02 =>; void-pointer 将指向 malloc'd MyData02 struct

当然,非常感谢针对不同方法的建议。

I've a situation like the following, and I'm not sure whether or not the std::string elements of the struct leak memory or if this is ok. Is the memory allocated by those two std::strings deleted when free(v) is called?

struct MyData
{
    std::string s1;
    std::string s2;
};

void* v = malloc(sizeof(MyData));

...

MyData* d = static_cast<MyData*>(v);
d->s1 = "asdf";
d->s2 = "1234";

...

free(v);

Leak or not?

I'm using the void-pointer because I have another superior struct, which consists of an enum and a void-pointer. Depending on the value of the enum-variable, the void* will point to different data-structs.

Example:

enum-field has EnumValue01 => void-pointer will point to a malloc'd MyData01 struct

enum-field has EnumValue02 => void-pointer will point to a malloc'd MyData02 struct

Suggestions for different approaches are very appreciated, of course.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你穿错了嫁妆 2024-12-14 06:41:38

您不应该在 C++ 程序中使用 malloc()free();他们不了解构造函数/析构函数。

使用newdelete 运算符。

You shouldn't be using malloc() and free() in a C++ program; they're not constructor/destructor-aware.

Use the new and delete operators.

够钟 2024-12-14 06:41:38

这是未定义的行为 - 由 malloc() 分配的内存未初始化,因此将其用作包含 string 对象的结构可能会导致任何结果;我预计会崩溃。由于在调用 free() 之前没有人调用析构函数,因此 string 对象不会被销毁,并且它们的缓冲区几乎肯定会泄漏。

That's undefined behavior - memory allocated by malloc() in uninitialized, so using it as a struct containing string objects can lead to anything; I'd expect crashing. Since no-one invokes the destructor before calling free(), string objects won't be destroyed and their buffers will almost definitely leak.

养猫人 2024-12-14 06:41:38

确实有泄漏。 free 不会调用 MyData 析构函数(毕竟它是一个 C 函数,对 C++ 的东西一无所知)。要么你应该使用 new/delete 而不是 malloc/free:


MyData* d = new MyData;
d->s1 = "asdf";
d->s2 = "1234";
delete d;

要么自己调用析构函数:


void* v = malloc(sizeof(MyData));
MyData* d = new (v) MyData; // use placement new instead of static_cast
d->s1 = "asdf";
d->s2 = "1234";
...
d->~MyData();
free(v);

正如 Sharptooth 指出的那样,你不能直接使用 malloc 分配的内存作为 MyData 结构而不进行初始化,所以你也必须自己这样做。要使用已分配的内存初始化 MyData,您需要使用placement new(请参见上面的代码)。

There is a leak indeed. free doesn't call MyData destructor (after all it's a C function which doesn't know anything about C++ stuff). Either you should use new/delete instead of malloc/free:


MyData* d = new MyData;
d->s1 = "asdf";
d->s2 = "1234";
delete d;

or call destructor by yourself:


void* v = malloc(sizeof(MyData));
MyData* d = new (v) MyData; // use placement new instead of static_cast
d->s1 = "asdf";
d->s2 = "1234";
...
d->~MyData();
free(v);

as sharptooth noted you can't directly use memory allocated by malloc as a MyData struct without initialization, so you have to do it by yourself as well. To initialize MyData using already allocated memory you need to use placement new (see in the code above).

你与昨日 2024-12-14 06:41:38

是的,因为构造函数和析构函数没有被调用。使用新建删除

Yes, because the constructor and destructor are not called. Use new and delete.

写下不归期 2024-12-14 06:41:38

即使您设法正确初始化 s1 和 s2,仅执行 free(d) 也不会回收为 s1 和 s2 动态分配的任何内存。您确实应该通过 new 创建 *d 并通过 delete 销毁,这将确保 s1 和 s2 的正确销毁(以及初始化)。

Even if you manage to initialize s1 and s2 properly, simply doing free(d) won't reclaim any memory dynamically allocated for s1 and s2. You should really create *d through new and destroy through delete, which will ensure proper destruction of s1 and s2 (and initialization as well).

何其悲哀 2024-12-14 06:41:38

是的,您可能正在泄漏,并且您的字符串也没有正确构造。程序的行为是未定义的,这意味着一切都会出错。

完成您正在做的事情最接近的有效方法是放置new。尽管如此,使用一些公共基类和适当的 C++ 多态性会更好。

如果可能的类型不相关,您可以使用 Boost.Any 或 Boost.Variant

Yes, you are probably leaking, and your strings aren't properly constructed, either. The program's behaviour is undefined, meaning everything is going to go wrong.

The closest valid way to do what you're doing is placement new. Still, you'd be better off with some common base class and proper C++ polymorphism.

If the possible types are unrelated, you can use Boost.Any or Boost.Variant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文