O bloco de código a seguir está compilando e funcionando bem.
Qeus-1. É seguro memset um struct que contém outro stuct com ponteiro inteligente como uma variável de membro? (como o código de exemplo abaixo)
Ques-2. É seguro definir por memset uma estrutura que contém membros de ponteiro inteligente?
A estrutura de código a seguir é parte de um projeto legado em que essas estruturas hierárquicas têm centenas de outros membros (membros POD ou não POD)
#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;
}
Não, nunca use memset
em qualquer estrutura que não seja POD .
No entanto, seu código não está fazendo isso, ele só está chamando memset
em _School
que é POD como ele contém apenas um ponteiro, chamando memset
on _Class
ou _Globals
teria um comportamento indefinido. No entanto, prefiro remover o memset
e adicionar um construtor ao _School
qual inicializa pSchool
para nullptr
:
struct _School {
_Class *pSchool;
_School() : pSchool(nullptr) {}
};
Você precisa usar new
em código C ++ em vez de malloc
como malloc
não chama construtores de classe.
Observe também que os identificadores que começam com sublinhado seguido por um caractere maiúsculo são reservados para uso pelo compilador / biblioteca padrão.
O código completo seria:
#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;
}
Este artigo é coletado da Internet.
Se houver alguma infração, entre em [email protected] Delete.
deixe-me dizer algumas palavras