Casting von int nach void-Zeiger
Guten Tag,
Ich habe gerade angefangen zu lernen, void-Zeiger in c++ und jetzt Schreibe ich binären Baum, wo ein Wert gespeichert, jeder Knoten ist void-Zeiger auf einen Wert.
struct TreeNode
{
int count;
void* data;
TreeNode *left;
TreeNode *right;
};
Das problem trat im ersten Verfahren-add-Methode.
meine Methode nimmt jetzt ein int parameter und nichts zurückgeben
Habe ich ganz am Anfang erstellen Sie neue Knoten.
Dafür müsste ich mir den cast von integer in die leere.
Programm compiliert und erstes element fügt root richtig-aber wenn ich dann senden Sie eine andere Nummer zu Methode speichert diese im root wieder.
also, wenn Sie in der main habe ich so etwas wie
Baum.addToTree(12);
Baum.addToTree(13);
als würde es speichern, 12 erste und als direkt nach der else-Anweisung(code unten), wie das root->Daten i 13.
void Tree::addToTree(int num)
{
if(root==NULL){
root= new TreeNode();
root->data=#
//((int *)(root->data)) = num;//i tried to convert to void* in this way but it give me segmentation fault
root->left=NULL;
root->right=NULL;
}
else{
//here root value is already changed
int *intPtr = static_cast<int*>(root->data);
cout << "key2" << *intPtrT << endl;
//TreeNode* current= insert(num,root);
}
}
wie ich verstanden habe das ist weil ich benutze &num so meine parameter immer Riss in einem Ort und einer Wurzel "verbunden" zu &num es zu ändern, wie gut.
Ich habe versucht, Lösungen zu finden, aber war erfolglos.
Gibt es eine Möglichkeit, cat int, void-pointer?
- Sie sind nicht Gießen Sie den Zeiger auf void in int. Sie Gießen es auf einen Zeiger auf int.
((int *)(root->data)) = num
kann nicht kompilieren. Müsste((int *)(root->data)) = &num
oder*((int *)(root->data)) = num
. Welche war es?- Danke allen für Ihre Antwort.Sie waren sehr hilfreich.Ich habe "new int(num)"-es funktioniert. Zu der Vorlage haben-das wäre effizienter für sicher, aber ich bin ein student jetzt und meine Aufgabe klar brauchen wir leere ,die ich nicht sehr angemessen,wie ich schon sagte)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste von allen, es gibt sehr sehr wenige Gründe, Sie zu speichern etwas wie eine
void*
statt über eine stark typisierte Methode (z.B. template). Ihre gesamte problem verschwindet ziemlich schnell, wenn Sie den code ändern, umSagte, das problem, das Sie haben ist, dass Sie speichern die Adresse einer kopieren, die gehen Weg, sobald die Funktion geht out of scope:
Das problem der Linie sein sollte:
Und Sie müssen ordnungsgemäß löschen Sie den Speicher, wenn Sie fertig sind (z.B. wenn Ihre Struktur wird zerstört).
Alternativ, wenn Sie geschehen, werden auf einem system, wo
sizeof(void*) == sizeof(int)
können Sie dies tun,Einfach behandeln die
void*
Mitglied als integer. Dies funktioniert nicht auf Systemen, auf denenint
ist größer alsvoid*
.Zunächst sollten Sie entscheiden, ob Sie möchten, um Daten zu speichern, durch einen Wert oder einen Zeiger darauf.
Im ersten Fall, dass ein Zeiger nur nutzlos, Sie könnte verwenden Sie eine Vorlage, wie:
Dies funktioniert auch mit Zeigern (wie
T *data ... data = new int()
).In Fall, dass Sie wollen, um zu speichern einen Zeiger auf Daten können Sie auch eine Vorlage verwenden, die mit einem Typ-parameter, oder verwenden Sie einen gemeinsamen Vorfahren-Klasse und dann zu Unterklasse mit den erforderlichen Typen, zB:
Schließlich storying eine
int
innerhalb einervoid*
Zeiger ist etwas, was nicht so gefördert, mitvoid*
in C++ zu erreichen Polymorphismus wird davon abgeraten im Allgemeinen, da Sie noch viele andere tools, die sind sicherer und zuverlässiger.Wenn Sie wirklich wollen, zu speichern
int
innerhalb einervoid*
dann sollten Sie dasintptr_t
Typ ist eine ganze Zahl, die umwandelbar in einen Zeiger. Eg:Diese speichern den Wert der integer-direkt als Adresse in die
void*
. Dies bedeutet, dass man nicht dereferenzieren Sie den Zeiger selbst.Übrigens
root->data=&num
ist falsch, da Sie die Zuordnung zudata
die Adresse eine automatische zugewiesene variable wird ungültig, wenn man Sie verlässt Ihren Anwendungsbereich.Ein problem, das ich sehe, ist nicht die Antwort, nur ein problem)... in der Funktion
Zuweisung der Adresse eines automatische variable
data
. Das Problem ist, dass, sobald die Funktion beendet wird, wird diese variable nicht mehr vorhanden (es wird gesagt, um Gültigkeitsbereich) und so Sie haben, was ist bekannt als eine baumelnden Zeiger, d.h. ein Zeiger verweist auf einen Speicherbereich, der nicht mehr verwendet oder nicht mehr für den ursprünglichen Zweck, dass der Zeiger erwartet.Du dieses Problem beheben könnte an drei stellen.
root->data = (void *)num
(Hinweis: ich werfe die Wert der Variablen auf einenvoid*
und nicht die Adresse der Variablen). Oder Sie könnte, wie ich das sehe,root->data = new int(num);
. In diesem Fall müssen Sie sicherstellen, dassdelete
den Speicher, wenn der Baum zu zerstörenDen anderen etwas von dir Frage wo hast du den Kommentar
Der Grund, warum das fehlschlägt, weil
root->data
an dieser Stelle nur einen Zeiger... es nicht überall (sinnvoll) noch. So, wenn Sie versuchen, Sie zu dereferenzieren es, Sie versuchen, Zugriff auf einige Speicher, bedeutet "existieren" noch (entweder pointer ist NULL oder hat eine ungültige Adresse), und so werden Sie seg fault.Wenn ein pointer auf diese Weise müssen Sie erstellen von Speicher und stellen Sie dann die Zeiger zeigen auf, dass der Speicher, z.B.
root->data = new int;
. Sobald Sie das getan haben, können Sie dann einen Wert zuweisen, die Position im Speicher, z.B.*(root->data) = 1234;