2010-05-05 12 views
6

Hé les gars. Je travaille sur la réparation du code plus ancien pour mon travail. Il est actuellement écrit en C++. Ils ont converti l'allocation statique en dynamique mais n'ont pas édité les memsets/memcmp/memcpy. C'est mon premier stage de programmation si vide avec ma question de newbe.Utiliser memset sur les structures en C++

Le code suivant est en C, mais je veux avoir en C++ (j'ai lu que malloc est pas une bonne pratique en C++). J'ai deux scénarios: Premièrement, nous avons créé f. Ensuite, vous utilisez & f afin de remplir avec zéro. La seconde est un pointeur * pf. Je ne suis pas sûr de savoir comment définir pf à tous les 0 comme l'exemple précédent en C++.

Pourriez-vous simplement faire pf = new foo au lieu de malloc et ensuite appeler memset(pf, 0, sizeof(foo))?

struct foo { ... } f; 
memset(&f, 0, sizeof(f)); 

//or 

struct foo { ... } *pf; 
pf = (struct foo*) malloc(sizeof(*pf)); 
memset(pf, 0, sizeof(*pf)); 
+1

Cela dépend de ce qui est dans foo! –

Répondre

8

Oui, mais seulement si foo est un POD. S'il a des fonctions virtuelles ou n'importe quoi d'autre à distance C++ ish, n'utilisez pas memset car il écrasera tous les internes de la structure/classe.

Ce que vous voulez probablement faire au lieu de memset est de donner foo un constructeur pour initialiser explicitement ses membres.

Si vous souhaitez utiliser nouveau, n'oubliez pas la suppression correspondante. Mieux encore serait d'utiliser shared_ptr :)

+0

Merci Ben. Après avoir regardé d'autres fichiers, j'ai remarqué qu'ils utilisaient la méthode new-> delete pour initialiser plus que pour créer un constructeur pour la structure. Je vais aller avec ça car ils n'ont pas de fonctions virtuelles.Merci pour l'aide. – garry

+0

@garry: lors de l'utilisation de 'new', le constructeur est toujours appelé. Vous pouvez initialiser ses attributs ici. –

+3

Pédanterie mineure qu'en C et C++, même avec les types POD, il est techniquement indéfini de simplement utiliser 'memset' pour zéro mémoire, puis de lire cette mémoire comme autre chose que les types' char' et garanti-no-padding -bits '(u) types intN_t'. En pratique, votre implémentation fera en sorte que tous les 0 octets signifient un pointeur nul, un flottant 0.0 (comme dans IEEE754), etc., mais historiquement, ce n'est pas toujours le cas de toutes les implémentations. –

2

Oui, cela fonctionnerait. Cependant, je ne pense pas que malloc soit nécessairement une mauvaise pratique, et je ne le changerais pas juste pour le changer. Bien sûr, vous devriez vous assurer de toujours faire correspondre les mécanismes d'allocation correctement (nouveau-> supprimer, malloc-> gratuit, etc.).

Vous pouvez également ajouter un constructeur à l'struct et l'utiliser pour initialiser les champs.

3

Pouvez-vous? Oui probablement. Devrais-tu? Non

Bien qu'il ne fonctionnera probablement, que vous perdez l'état que le constructeur a construit pour vous. Ajoutant à cela, que se passe-t-il lorsque vous décidez d'implémenter une sous-classe de cette structure? Ensuite, vous perdez l'avantage du code réutilisable que C++ OOP offre.

Qu'est-ce que vous devez faire est de créer à la place un constructeur qui initialise les membres pour vous. De cette façon, lorsque vous sublimez cette structure plus tard sur la ligne, vous utilisez simplement ce constructeur pour vous aider à construire les sous-classes. C'est gratuit, code sécurisé! utilise le!

Edit: La mise en garde à ce que si vous avez une énorme base de code déjà, ne changent pas jusqu'à ce que vous commencez à Dérivation de l'struct. Cela fonctionne comme maintenant.

2

Vous pourriez nouvelle foo (comme la manière standard en C++) et mettre en œuvre un constructeur qui initialise foo plutôt que d'utiliser memset.

E.g.

struct Something 
{ 
    Something() 
     : m_nInt(5) 
    { 

    } 

    int m_nInt; 
}; 

Aussi ne pas oublier si vous utilisez nouveau pour appeler supprimer lorsque vous avez terminé avec l'objet, sinon vous finirez avec des fuites de mémoire.

Questions connexes