probleme mit delete[]
-
Man sollte den reservierten Speicher auch immer "leeren" z.B. mit ZeroMemory nachdem man ihn initialisiert hat.
Sonst kann es sein, dass der erneut reservierete Speicher wieder an der alten Stelle landet und er mit den alten Daten gefüttert ist...
Vielleicht hilft das...
-
Die globalen Zeigervariablen mit 0 zu intitialisieren wäre auch ganz nützlich:
[code] AnsiString* order=0; AnsiString* starting_serial=0; AnsiString* quantity=0; AnsiString* assembly=0; [/code]
Wenn dein UnterProgramm A nämlich aus irgendeinen Grund nicht aufgerufen wird, knallt es sonst, weil die Zeiger irgendwo hinzeigen.
Edit:
Auch beim Deleten würde ich die Zeiger dann auf Null setzen.
-
Hawkxxx schrieb:
Man sollte den reservierten Speicher auch immer "leeren" z.B. mit ZeroMemory nachdem man ihn initialisiert hat.
Sonst kann es sein, dass der erneut reservierete Speicher wieder an der alten Stelle landet und er mit den alten Daten gefüttert ist...
Vielleicht hilft das...
Das ist Humbug. Selbst wenn neu angeforderter Speicher Reste alter Daten enthält, was soll da passieren? Ein vernünftiges Objekt initialisiert sich selbst, sodass es einen wohldefinierten Zustand nach der Erstellung hat.
@KPeter
Gibt´s einen Grund, warum du Pointer auf Elemente statt der Elemente selbst im Vektor ablegst?@OP
Von wievielen Datensätzen reden wir denn so ungefähr? Sind es eher hunderte, Tausende oder Millionen? Wenn´s nicht gerade in die Millionen geht ist KPeters Vorschlag die richtige Wahl, ich würde ihn allerdings etwas modifizieren:#include <vector> struct MyData { AnsiString Order; AnsiString StartingSerial; AnsiString Quantity; AnsiString Assembly; MyData() { } MyData( const AnsiString& order, const AnsiString& serial, const AnsiString& qty, const AnsiString& assembly ) : Order( order ), StartingSerial( serial ), Quantity( qty ), Assembly( assembly ) { } }; using namespace std; int main() { vector<MyData> Data; Data.push_back( MyData( "order", "serial", "quantity", "assembly" ) ); }
Hier muss nirgends mehr mit delete/delete[] aufgeräumt werden, das erledigt std::vector automatisch
-
DocShoe schrieb:
@KPeter
Gibt´s einen Grund, warum du Pointer auf Elemente statt der Elemente selbst im Vektor ablegst?Nö, war wohl 'n Schnellschuss...
Deine Variante ist schon ausgereifter.
mfg
kpeter
-
Besten Dank für eure Tipps... musste leider feststellen das ich bei den Pointern in der Schule wohl ein Fensterplatz hatte. Muss mir da zuerst einmal die Grundlagen aneignen. Danach werde ich Eure Tipps auprobieren.
-
Vieles ist mur nun klarer geworden, jedoch nich ganz alles:
was genau passiert hier?
MyData() { } MyData( const AnsiString& order, const AnsiString& serial, const AnsiString& qty, const AnsiString& assembly ) : Order( order ), StartingSerial( serial ), Quantity( qty ), Assembly( assembly ) { } };
binn ich richtig in der Annahme dass du hier so etwas wie ein Zeiger auf den Speicherort jedes Strings generierst?
Ist dies nötig, um danach mit
Data.push_back( MyData( "order", "serial", "quantity", "assembly" ) );
auf die Strings zuzugreifen?
und müsste das nicht auch so gehen?
Data.Order.push_back(Form1->ADOQuery1->FieldByName("Order")->AsString;)
Wobei mir der Compiler folgende Meldung bringt:
E2316 'order' is not a member of 'vector<MyData,allocator<MyData>>'Zur gestellten Frage mit der Anzahl Datensätze: es sollte sich höchstens um Tausende handeln.
-
binn ich richtig in der Annahme dass du hier so etwas wie ein Zeiger auf den Speicherort jedes Strings generierst?
Nein. Hier werden lediglich die membervariablen deiner Klasse mit den Argumenten deines Konstruktors befüllt. Siehe Initialisierungsliste.
Zeiger sind hier nicht im Spiel.Ist dies nötig, um danach mit
...
auf die Strings zuzugreifen?Hier wird nicht zuggegriffen sondern eines neues Objekt vom Typ MyData erzeugt und dann in den Vektor gepackt.
Das Danach geht so also nicht. Immerhin erwartet der Konstruktor von MyData 4 Parameter und nicht nur einen.
-
Was manche Anfänger wohl etwas verwirrt ist die Bedeutung des Kaufmannsund (&).
Je nach Kontext ist es der addressof operator oder eine Kennzeichnung für Referenzen. Im ersten Fall erhält man einen Zeiger auf irgendetwas zurück, im zweiten Fall möchte man explizit eine Referenz auf ein bereits bestehendes Objekt haben. (const) Referenzen werden häufig bei der Parameterübergabe an Funktionen verwendet, um unnötiges Kopieren zu vermeiden.Beispiel 1: Verwendung des addressof Operators und Typkennzeichner
int A; // Fall 1 int* pointer_to_A = &A; // Fall 2 int& reference_to_A = A;
Beispiel 2: Call-by-value und Call-by-reference
// 1) Call by value void func( AnsiString somestring ) { somestring = "func"; } // 2) Call by reference void gunc( AnsiString& somestring ) { somestring = "gunc"; } // 3) Call by const-reference void hunc( const AnsiString& somestring ) { // somestring kann hier nicht modifiziert werden } int main() { // call by value: // da AnsiString einen Konstruktor hat, der eine nullterminierte Zeichenkette // erwartet und daraus einen AnsiString erzeugen kann gelingt der Funktionsaufruf // es wird ein namenloses temporäres AnsiString Objekt erzeugt und an die // Funktion func übergeben. func( "Hello World" ); // call by reference // Ähnlich wie call by value, es wird ebenfalls ein namenloses temporäres // AnsiString erzeugt und eine Referenz darauf an die Funktion gunc übergeben. // ABER: Laut Standard sind Referenzen auf temporäre Objekte nicht erlaubt, // sodass der Compiler diese Zeile nicht übersetzen sollte gunc( "Hello World" ); // Korrekt geht´s so AnsiString s = "Hello World"; gunc( s ); // call by value: // Eine Kopie des AnsiStrings s wird erzeugt und an die Funktion func übergeben. // func( s ); // call by const-reference // Genauso wie call by reference, nur dass der Standard const Referenzen auf // temporäre Objekte ausdrücklich erlaubt, damit ist der folgende Funktionsaufruf // korrekt. hunc( "Hello World" ); }
-
langsam beginne ich ein wenig zu verstehen... aber: funktioniert das nicht:
struct OrderSet { AnsiString Order; AnsiString StartingSerial; AnsiString Quantity; AnsiString Assembly; OrderSet(){ } OrderSet( const AnsiString& order, const AnsiString& serial, const AnsiString& qty, const AnsiString& assembly ) : Order(order), StartingSerial(serial), Quantity (qty), Assembly (assembly){ } };
vector<OrderSet> traced;
...
if(records>0){ //Wenn Werte zurückgegeben: j=0; //Reset Counter Variable do{ //für alle Datensätze: traced.push_back( OrderSet (Form1->ADOQuery1->FieldByName("Order")->AsString),(Form1->ADOQuery1->FieldByName("Assembly")->AsString),(Form1->ADOQuery1->FieldByName("Starting_Serial")->AsString),(Form1->ADOQuery1->FieldByName("Quantity")->AsString));//kopiere Menge Form1->ADOQuery1->Next(); //Nächster Datensatz j++; //inkrement Zählervariable }while(j<records);
Kann ich nicht direkt aus der ADO-Komponente kopieren?
Fehlermeldung des Compilers:
E2285 Could not find a match for 'OrderSet::OrderSet(AnsiString)'
-
schau dir deine Klammern mal ganz genau an, nur hinter dem letzten AsString darf eine - mit der push-back sinds dann 2 - stehen, nicht hinter den anderen, da alle Werte innerhalb der OrderSet-Klammerung stehen sollten