Comment utiliser une chaîne C++ dans une structure lorsque la fonction malloc()-ing la même structure?
J'ai écrit le programme d'exemple suivant, mais il se bloque avec une erreur de segmentation. Le problème semble être avec l'aide de malloc
et std::string
s dans la structure.
#include <iostream>
#include <string>
#include <cstdlib>
struct example {
std::string data;
};
int main() {
example *ex = (example *)malloc(sizeof(*ex));
ex->data = "hello world";
std::cout << ex->data << std::endl;
}
Je ne peux pas comprendre comment le faire fonctionner. Toutes les idées si c'est encore possible d'utiliser malloc()
et std::string
s?
Merci, Boda Cydo.
OriginalL'auteur bodacydo | 2010-08-05
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas
malloc
une classe non triviale de constructeur en C++. Ce que vous obtenez à partir demalloc
est un bloc de raw de la mémoire, qui ne contient pas correctement objet construit. Toutes tentatives d'utilisation de cette mémoire comme un "vrai" objet échouera.Au lieu de
malloc
-ing objet, utiliseznew
Votre code d'origine peut être obligé de travailler avec
malloc
ainsi, en utilisant la séquence suivante:malloc
de la mémoire brute d'abord, la construction de l'objet dans la mémoire brute deuxième:La forme de
new
utilisé ci-dessus est appelé "le placement de nouvelles". Cependant, il n'y a pas besoin de toute cette supercherie dans votre cas.Vous pouvez utiliser
new(std::nothrow) example
afin de rendrenew
retour de pointeur null au lieu de lancer des exceptions. Vous devez inclure l'en-tête<new>
à utiliserstd::nothrow
constante.Si vous voulez vraiment
new
pour retourner un pointeur null en cas d'échec, l'utilisationnew(nothrow) example
. Mais vraiment, vous devriez simplement utilisertry
/catch
pour attraper la levée d'une exception. (Lestd::string
affectation, par exemple, pourrait également lever une exception si elle ne parvient pas à allouer la mémoire.)Cela a été très utile, car je suis en utilisant une bibliothèque de il faut - moi d'utiliser leur coutume alloc de commande pour des objets du passé dans leurs appels de fonction, mais n'a fourni aucun moyen de l'utiliser avec des dérivations de leurs structures qui contiennent non négligeable des structures. Super Réponse!
OriginalL'auteur AnT
Pour un
class
oustruct
comme votreexample
, la réponse correcte est d'utilisernew
pasmalloc()
pour attribuer à une instance. Seulementoperator new
sait comment appeler les constructeurs pour lesstruct
et de ses membres. Votre problème est causé par la chaîne membre n'ayant jamais été construit.Cependant, il y a rare cas où il est important qu'un patch de mémoire agir comme si elle est titulaire d'une instance d'une classe. Si vraiment vous avez un tel cas, alors il y a une variation de
operator new
qui permet à l'emplacement de l'objet spécifié. Ceci est appelé un "le placement de nouvelles" et doit être utilisé avec beaucoup de soin.En utilisant le placement de nouvelles, vous êtes tenu de fournir une région de la mémoire de la bonne taille et l'alignement. Ne fournissant pas de la bonne taille ou l'alignement sera la cause mystérieuse que les choses aillent mal. Alignement Incorrect est généralement plus rapide à cause d'un problème, mais peut également être mystérieux.
Aussi, avec un stage de nouvelles, vous prenez la responsabilité d'appeler le destructeur par la main, et en fonction de l'origine du bloc de mémoire, de la diffuser à son propriétaire.
Dans l'ensemble, sauf si vous savez déjà vous avez besoin d'un placement de nouvelles, vous avez presque certainement n'avez pas besoin. Il a des utilisations légitimes, mais il y a des recoins obscurs de cadres et de pas quotidien.
OriginalL'auteur RBerteig
Allocation de mémoire avec
malloc
ne pas appeler tous les constructeurs. Ne pas mélanger le style C répartition des objets en C++. Ils ne jouent pas bien ensemble. Au lieu de cela, utilisez lanew
opérateur à allouer des objets en C++ code:C'est plus intelligent de code et fera appel à la
std::string::string()
constructeur pour initialiser la chaîne, qui va corriger l'erreur que vous voyez. Et n'oubliez pas de le supprimer lorsque vous avez terminé pour libérer de la mémoire, et appeler les destructeurs:OriginalL'auteur John Kugelman
Le problème est que
malloc
n'appelle pas le constructeur deexample
. Depuis unstring
est généralement représenté comme un pointeur sur la pile, il est réglé à zéro, et vous déréférencement d'un pointeur null. Vous avez besoin d'utilisernew
à la place.OriginalL'auteur rlbond
vous ne devez pas utiliser
parce que ce que sizeof(*ex) retour est égale à la taille de long ou de la taille d'un int, qui est due à différents compiler environnante.
vous pouvez utiliser le code comme suit:
Quelqu'un va vers le bas-voter si vous n'êtes pas prudent (c'est mal).
OriginalL'auteur 开机就好