是否可以使用智能指针成员设置具有另一个结构的结构?
Is it okay to memset a struct which has an another struct with Smart pointer member?
以下代码块编译并运行正常。
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
,但它是合法和安全的。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么将一个结构的引用设置为等于另一个结构只会更改一个数据成员?
- 从另一个 cpp 文件更改结构内、映射键内的变量
- 如何将一个结构的字符数组复制到结构的另一个字符数组中?
- 如何将数据从一个结构链接到另一个结构
- 是否可以使用智能指针成员设置具有另一个结构的结构?
- std::transform 将一个结构数组复制到另一个结构数组
- C++将结构复制到另一个程序的资源
- 结构新手,我对如何从 void 函数中返回值并将其放入另一个函数感到困惑
- 可以访问一个类中的播放器结构,但不能访问另一个类中的播放器结构
- 如何在另一个结构中初始化结构数组?
- 在另一个结构中声明内部结构会导致错误:结构使用无效
- 通过 C++ 中的另一个结构成员访问结构
- 难以从另一个结构中的函数返回结构
- 有没有办法将一个对象注入到另一个对象的结构中?
- 如何制作一个结构程序,在其中可以存储无限量的数据,以便每次您想要时都可以将另一个产品添加到列表中?
- 将一个结构的值复制到另一个结构
- 结构C++可以用 0 初始化,但不能用另一个 int 初始化
- 如何将矢量结构从一个标头文件传递到另一个标头文件中的类
- 是否可以定义一个在外部"C"块中继承另一个结构的结构?