是否可以使用智能指针成员设置具有另一个结构的结构?

Is it okay to memset a struct which has an another struct with Smart pointer member?

本文关键字:结构 另一个 设置 可以使 智能 指针 成员 是否      更新时间:2023-10-16

以下代码块编译并运行正常。

Qeus-1。将包含另一个结构的结构与智能指针作为成员变量进行内存设置是否安全?(如下面的示例代码(

问题-2。对包含智能指针成员的结构进行内存设置是否安全?

以下代码结构是遗留项目的一部分,其中此层次结构具有数百个其他成员(POD 或非 POD memeber(

#include <iostream>
#include <map>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <memory>

typedef struct _Globals{
std::shared_ptr<std::map<int, std::string> > rollNamePair;
} _Globals;
struct _Class {
struct _Globals Globals;  // global vars
};
struct _School {
struct _Class *pSchool;
};
int main()
{
struct _School abc;
memset(&abc, 0, sizeof(struct _School));
abc.pSchool= (struct _Class*) malloc(sizeof(struct _Class));
abc.pSchool->Globals.rollNamePair= std::make_shared<std::map<int, std::string> >();
(*abc.pSchool->Globals.rollNamePair)[1]= "John";
(*abc.pSchool->Globals.rollNamePair)[2]= "Paul";
std::cout << (*abc.pSchool->Globals.rollNamePair)[1] << "n";
std::cout << (*abc.pSchool->Globals.rollNamePair)[2];
return 0;
}

不,切勿在任何非 POD 的结构上使用memset

但是,您的代码没有这样做,它只是在 POD_School上调用memset,因为它只包含一个指针,在_Class_Globals上调用memset会有未定义的行为。但是,我更喜欢删除memset并向_School添加一个构造函数,该构造函数将pSchool初始化为nullptr

struct _School {
_Class *pSchool;
_School() : pSchool(nullptr) {}
};

您需要在C++代码中使用new而不是malloc,因为malloc不调用类构造函数。

另请注意,以下划线开头,后跟大写字符的标识符保留供编译器/标准库使用。

完整的代码将是:

#include <map>
#include <string>
#include <memory>
#include <iostream>
struct Globals{
std::shared_ptr<std::map<int, std::string> > rollNamePair;
};
struct Class {
Globals Globals;  // global vars
};
struct School {
Class *pSchool;
School() :pSchool(nullptr) {}
};
int main()
{
School abc;
abc.pSchool= new Class();
abc.pSchool->Globals.rollNamePair = std::make_shared<std::map<int, std::string> >();
(*abc.pSchool->Globals.rollNamePair)[1] = "John";
(*abc.pSchool->Globals.rollNamePair)[2] = "Paul";
std::cout << (*abc.pSchool->Globals.rollNamePair)[1] << "n";
std::cout << (*abc.pSchool->Globals.rollNamePair)[2];
delete abc.pSchool;
return 0;
}

为了解决第二个问题,如果你有一个结构体

struct G {
std::shared_ptr<T> ptr;
};

包含一个智能指针作为其成员,然后执行

G g;
std::memset(&g, 0, sizeof(G));

绝对不安全,因为您覆盖g.ptr已经构造的非 POD 类型的对象。

你可以做的是这样的:

std::aligned_storage_t<sizeof(G), alignof(G)> storage; // Raw storage of some POD type
std::memset(&storage, 0, sizeof(G));
auto g = new (&storage) G;
g->ptr = std::make_shared ... ;
// ...
std::destroy_at(g);

在这个特定示例中没有理由使用memset,但它是合法和安全的。

相关文章: