Allokier-Fehler
-
Hi
,ich möchte meiner Klasse Speicher allokieren mit malloc. In der Klasse ist eine CString Variable.
Mit Integern funktioniert das.
Wenn ich nun auf die CString Variable zugreifen will, gibt er eine Fehlermeldung aus und sagt <schlechtes Ptr>.Ich hab folgendermaßen allokiert:
im Headerstruct STRCT_SORTHISTORIEDATEN_Test { int m_iTag; // wird anhand des Datums identifiziert und als eine Nummer gespeichert: CTime:getTime(); CString csDatum; };Dann erstellt
STRCT_SORTHISTORIEDATEN_Test *m_pstrctSortHistorieDatenA; int m_strctNeueImpfdaten_Anzahl = 20; m_pstrctSortHistorieDatenA = (STRCT_SORTHISTORIEDATEN_Test*) malloc(m_strctNeueImpfdaten_Anzahl*sizeof(STRCT_SORTHISTORIEDATEN_Test)); // Allokiere 10 ArraysNun will ich csDatum einen Wert zuweisen mit
m_pstrctSortHistorieDatenA[0].csDatum = _T("d"); // Fehler, denn m_pstrctSortHistorieDatenA[0].csDatum hat ein <schlechte ptr>Wäre super, wenn mir jmd helfen könnt!
-
WHAT THE... was machst du denn da? Und die Aneinanderreihung der Buchstaben macht mich ganz wirr im Kopf. Was willst du genau machen? Willst du 10 Arrays oder ein Array mit 10 Elementen? Was ist das Ziel deines Programmstücks?
-
[quote="AnnaTX"]
malloc(m_strctNeueImpfdaten_Anzahl*sizeof(STRCT_SORTHISTORIEDATEN_Test)); // Allokiere 10 ArraysAbgesehen davon, ist das in C++ undefined behaviour.
-
out schrieb:
AnnaTX schrieb:
malloc(m_strctNeueImpfdaten_Anzahl*sizeof(STRCT_SORTHISTORIEDATEN_Test)); // Allokiere 10 ArraysAbgesehen davon, ist das in C++ undefined behaviour.
Das sehe ich jetzt so auf Anhieb nicht. Mag mich wer aufklaeren? Also abgesehen davon, dass der Konstruktor von CString nicht aufgerufen wird, was prinzipiell auch danach geschehen kann.
-
out schrieb:
WHAT THE... was machst du denn da? Und die Aneinanderreihung der Buchstaben macht mich ganz wirr im Kopf. Was willst du genau machen? Willst du 10 Arrays oder ein Array mit 10 Elementen? Was ist das Ziel deines Programmstücks?
oh, ich meinte 20, nicht 10.
Ich will im Prinzip das hier:
STRCT_SORTHISTORIEDATEN_Test m_pstrctSortHistorieDatenA[20];Aber da ich die Klasse später evtl. vergrößern will (mit realloc), da ich evtl mehr als 20 Elemente brauche, will ich es als Pointer deklarieren und mit malloc 20 Element von STRCT_SORTHISTORIEDATEN_Test erstellen.
Verstehst Du was ich meine?Ja, ich schreibe zu Vaiablen immer die Typkürzel vor dem Namen. Ich weiß, dass sieht doof aus. Wie machst Du das denn ?
-
std::vector
-
Die Frage ist: C oder C++?
C++: Nimm einfach std::vector. Problem gelöst.
C: Au weia. Mach erstmal die ganzen Casts weg, damit die nicht eventuelle Fehler verdecken und schraub Compilerwarnungen hoch. Ansonsten bist du mit malloc/realloc schon auf dem richtigen Weg. Falls trotz warnungsloser Übersetzung immer noch nichts funktionieren sollte zeig mal mehr Code, siehe dritter Link in meiner Signatur.
-
AnnaTX schrieb:
Ich will im Prinzip das hier:
STRCT_SORTHISTORIEDATEN_Test m_pstrctSortHistorieDatenA[20];Aber da ich die Klasse später evtl. vergrößern will (mit realloc), da ich evtl mehr als 20 Elemente brauche, will ich es als Pointer deklarieren und mit malloc 20 Element von STRCT_SORTHISTORIEDATEN_Test erstellen.
Verstehst Du was ich meine?Ja, du weißt im Voraus nicht, wie viele Elemente du schlußendlich wirklich brauchst. Das kommmt relativ oft vor, dieses Problem. Lösung: std::vector, alles andere ist hier fehl am Platz.
AnnaTX schrieb:
Ja, ich schreibe zu Vaiablen immer die Typkürzel vor dem Namen. Ich weiß, dass sieht doof aus. Wie machst Du das denn ?
Ich schreibe alles klein. Wörter trenne ich durch einen Unterstrich: int number_of_xy = z;
-
std::vector verwendet namespace und ich will auf möglichst viele Zusatzbibliotheken verzichten, damit es auf möglichst vielen Rechnern reibungslos und ohne viel zu installieren läuft.
Ich habe sonst nur WinApi-Befehle.
Ich versuche es mal mit den Compiler-Warnungen und melde mich nochmal.Vielen Dank für Eure Antworten

-
AnnaTX schrieb:
Ja, ich schreibe zu Vaiablen immer die Typkürzel vor dem Namen. Ich weiß, dass sieht doof aus. Wie machst Du das denn ?
Wie würdest du denn diesen Typ abkürzen? Bitte mit Begründung!
template <typename T1, typename T2> using Typ = std::function<std::array<T1, 3>&(const std::vector<T2>&, int)>;Das ist eine Klasse, aber auch aufrufbar, aber auch ein Template und irgendwie funktionspointerartig. Und das ist nur die std::function, die ganze Typinformation im Inneren musst ja auch noch komplett rein. Wie macht man das zum Beispiel mit der 3?
Typ T10T20Ccp2T11T12CAT11T10T213Rc2T13T23ApconstRT13T20T23di_foo?AnnaTX schrieb:
std::vector verwendet namespace und ich will auf möglichst viele Zusatzbibliotheken verzichten, damit es auf möglichst vielen Rechnern reibungslos und ohne viel zu installieren läuft.
Du bist sehr verwirrt. Dir fehlen allerwichtigste Grundlagen. Hast du früher mal Pascal gemacht? Du bringst hier Dinge durcheinander. namspace ist so sehr Bibliothek, wie das Semikolon eine Bibliothek ist.
-
AnnaTX schrieb:
std::vector verwendet namespace und ich will auf möglichst viele Zusatzbibliotheken verzichten, damit es auf möglichst vielen Rechnern reibungslos und ohne viel zu installieren läuft.
Die Standardbibliothek ist bei _jedem_ C++-Compiler dabei. Das ist keine Zusatzbibliothek.
-
AnnaTX schrieb:
std::vector verwendet namespace und ich will auf möglichst viele Zusatzbibliotheken verzichten, damit es auf möglichst vielen Rechnern reibungslos und ohne viel zu installieren läuft.
Ich habe sonst nur WinApi-Befehle.
Hahaha danke dass du mir den Tag versüßt hast. Die beiden Sätze hintereinander sind einfach zu gut.

Kellerautomat schrieb:
Die Standardbibliothek ist bei _jedem_ C++-Compiler dabei. Das ist keine Zusatzbibliothek.
Nu ja.. es gibt auch noch freestanding implementations, die brauchen <vector> nicht mitzuliefern.
@AnnaTX
Nimm einfach std::vector, wenn dein Programm auch auf Digitaluhren, Waschmaschinen und in Aufzügen laufen soll, meldeste dich noch mal. Und du solltest dir mal den Unterschied zwischen der Standardbibliothek und dynamisch und statisch gelinkten externen Bibliotheken angucken.
-
Wenn du std::vector nicht verwenden kannst, weil dein Compiler von 1993 ist oder so, dann benutz wenigstens new statt malloc, damit die Objekte alle korrekt konstruiert werden. Das was du da vorhast ist mit malloc nicht machbar.
-
Kellerautomat schrieb:
AnnaTX schrieb:
std::vector verwendet namespace und ich will auf möglichst viele Zusatzbibliotheken verzichten, damit es auf möglichst vielen Rechnern reibungslos und ohne viel zu installieren läuft.
Die Standardbibliothek ist bei _jedem_ C++-Compiler dabei. Das ist keine Zusatzbibliothek.
Noch viel einfacher: die Standardbibliothek brauchst du nur auf dem Rechner, auf dem du kompilierst. Das fertige Programm kannst du dann munter rumreichen, da brauchst du keine "Standardbibliothek-dll"
-
Der grundlegende Fehler, der hier passiert ist, dass der Konstruktor von CString nicht aufgerufen wird. Malloc reserviert nur Speicher mit zufälligen Inhalt. Dem int ist das egal, da jedes Bitmuster ein gültiges int ist. Bei CString sieht das anders aus. Der hält sicher einen Zeiger auf seine Daten und wenn dieser mit einem zufälligen Bitmuster gefüllt ist, dann zeigt der Zeiger halt irgendwo hin.
Hier wurden ja bereits Lösungen vorgeschlagen. Die naheliegende wäre statt malloc new zu verwenden. new ruft auch den Konstruktor auf. Also statt:
m_pstrctSortHistorieDatenA = (STRCT_SORTHISTORIEDATEN_Test*) malloc(m_strctNeueImpfdaten_Anzahl*sizeof(STRCT_SORTHISTORIEDATEN_Test));einfach
m_pstrctSortHistorieDatenA = new STRCT_SORTHISTORIEDATEN_Test[m_strctNeueImpfdaten_Anzahl];Der Code ist dann ein wenig weniger grausam. Aber bitte daran denken, mit
delete[] m_pstrctSortHistorieDatenAwieder aufzuräumen.Besser ist natürlich std::vector. Und ja, Du kannst Dich darauf verlassen, dass std::vector einfach verfügbar ist, wenn Du in C++ programmierst.
-
knivil schrieb:
out schrieb:
AnnaTX schrieb:
malloc(m_strctNeueImpfdaten_Anzahl*sizeof(STRCT_SORTHISTORIEDATEN_Test)); // Allokiere 10 ArraysAbgesehen davon, ist das in C++ undefined behaviour.
Das sehe ich jetzt so auf Anhieb nicht. Mag mich wer aufklaeren? Also abgesehen davon, dass der Konstruktor von CString nicht aufgerufen wird, was prinzipiell auch danach geschehen kann.
Sorry, ich habe falsch zitiert. Ich meinte dieses Konstrukt:
m_pstrctSortHistorieDatenA = (STRCT_SORTHISTORIEDATEN_Test*) malloc(m_strctNeueImpfdaten_Anzahl*sizeof(STRCT_SORTHISTORIEDATEN_Test)); // Allokiere 10 Arraysmallocgibt javoid*zurück, und das darf man in C++ nicht einfach so Casten. Ich darf vielleicht einen anderen Zeiger-Typ auf den Speicherbereich setzen, aber spätestens bei einer Dereferenzierung könnte das Ganze schief gehen. (Falls ich falsch liege, korrigiert mich)
-
out schrieb:
mallocgibt javoid*zurück, und das darf man in C++ nicht einfach so Casten. Ich darf vielleicht einen anderen Zeiger-Typ auf den Speicherbereich setzen, aber spätestens bei einer Dereferenzierung könnte das Ganze schief gehen. (Falls ich falsch liege, korrigiert mich)Ich korrigiere: Das ist durchaus definiert. Der Zeiger zeigt auf einen Speicherbereich, der groß genug ist, um eine Struktur vom Typ STRCT_SORTHISTORIEDATEN_Test zu konstruieren. Als nächstes könnte man ja den Konstruktor in-place aufrufen. Man darf nur nicht davon ausgehen, dass der Zeiger auf eine initialisierte Struktur zeigt.
-
AnnaTX schrieb:
ich möchte meiner Klasse Speicher allokieren mit malloc.
Warum? Du willst dir ja sicherlich auch nicht ins Knie tackern. Das tut nämlich weh und blutet dann sehr wahrscheinlich. Ähnlich masochistisch ist das dynamische Anlegen eines nicht-POD-Objekts per malloc. Es ist zwar im Rahmen des Möglichen, aber unnötig umständlich. Wenn du also keinen guten Grund hast: Lass die Finger von malloc für C++ Klassen.
AnnaTX schrieb:
In der Klasse ist eine CString Variable.
In Standard-C++ gibt's kein CString. In Standard-C++ gibt's aber zB. std::string. Ich tippe mal darauf, dass Du die CString-Klasse von Microsoft meinst. Gibt es einen guten Grund, warum du diese nutzen willst? So oder so sind das keine POD-Typen (POD = plain old data). Es sind Typen, deren Objekte speziell initialisiert und speziell de-initialisiert werden müssen. Und das leistet malloc gar nicht von alleine.