realloc
-
Und wenn du dir den ganzen Ärger mit der Speicherverwaltung ersparen willst, verwende lieber std::vector (o.ä.) anstelle der nackten Zeiger.
-
"unskilled" : Merkt man.

Mach doch mal C++ ... da sparst Du Dir und uns auch Deine Folgefrage der Art "Warum bekomme ich einen SeqFault ?", "Wieso fehlen da Zeichen ?", ...struct Pizza { unsigned long handle; //ein handle zum identifizieren (?; s.u.) string name; //Anzeigename string beschreibung; //Beschreibung dazu vector<float> preis; //preise }; typedef vector<Pizza> PizzaListe; typedef vector<PizzaListe> PizzaMenu; // Braucht man die wirklich als Typen oder reicht da nicht einfach eine entsprechende Variable ? ...Damit entällt jedes malloc(), realloc(), str___(), ... und alle möglicen anderen Komplikationen.
Übrigens @"Modellierung":
0.) "pizza_item" ist ein unglücklicher Name, weil er fachliche (soll eine Pizza abbilden) und technische (soll Bestandteil einer Liste sein) Bezeichnung mischt. Angesichts Deiner anderen "Benamsung" würde ich das Teil einfach "pizza" nennen. Was ein "PizzaMain" sein soll, weiß ich nicht...
1.) Ich würde mir gründlich überlegen, WAS eine Pizza identifizieren soll ... ob das wirklich ein "Handle" sein soll, oder ob nicht tatsächlich der name selbst die Pizza bereits eindeutig beschreibt. Was nützen Dir zwei verschiedene "Pizza Margerita" (die jeweils noch n verschiedene Preise haben können.... und welchen Ärger können sie Dir einhandeln ?
2.) Woran soll ein Nutzer den aktuellen Preis bestimmen, wenn er nur eine Liste von Preisen hat ? Wenn die jeweiligen Preise eine Bedeutung haben, sollte das über ein Attribut von preis ersichtlich sein ... so "unsichtbare Bedingungen" wie "Der 1. Preis ist immer der für Kunden, der 2. immer der für Angestellte, der 3. ...." beissen einem irgendwann immer in der Hintern. Das sollte auch direkt mit modelliert werden. Das geht z.B. über eintypedef pair<string, unsigned int> Preis; struct Pizza { // ... vector<Preis> preise; };oder direkt in der
struct Pizza { // ... map<string, unsigned int> preise; };(Alternativ kann natürlich auch ein enum zur "Preisart-Identifikation" dienen)
3.) Ich würde den Preis in Cent als unsigned int ablegen. Spart Dir Rundungsprobleme und feiner als Cent brauchst Du doch eh nicht.
Gruß,
Simon2.
-
danke für eure antworten - vor allem @simon :>
ich meld mich wieder, wenns nicht klappt bzw ich fragen hab ^^
@simon: die preise haben schon ne beschreibung - die ist in der liste (als beschreibung gekennzeichnet ^^)die idee mit dem preis als int und nicht als float fand ich auch ganz ok - und hab es auch direkt so gemacht - jz geht alles - warum auch immer ^^
danke : >
//edit habs jz auch mit new gemacht, aber irgendwie hab ich da was falsch gemacht

this->Main->lists[this->Main->listcount-1].beschreibung = new char*[PpI]; for (unsigned __int8 i = 0; i < PpI; i++) { this->Main->lists[this->Main->listcount-1].beschreibung[i] = new char; strcpy (this->Main->lists[this->Main->listcount-1].beschreibung[i], Beschreibungen[i]); }Ist hier irgend ein Fehler drin?
Weil, wenn ich danach von außen darauf zugreife, kommt nen doller Zugriffsfehler - bei Allem anderen aber ist alles in Ordnung
Danke schon mal und noch mal und überhaupt ^^Tom
-
ok - der Fehler lag/liegt nicht an der Schleife an sich sondern immer noch an (falschen) Speicherzugriffen :<
noch mal den Code, wie er jetzt ist:
//structs struct pizza_item { unsigned __int32 handle; char *name; char *beschreibung; unsigned __int16 *preis; }; struct pizza_list { unsigned __int16 id; char *name; char *beschreibungen; unsigned __int8 ppi; //Preise pro Item signed __int16 itemcount; pizza_item **items; }; struct pizza_main { signed __int16 listcount; pizza_list **lists; };und
void pizza::newmain (void) { this->Main = new pizza_main; this->Main->listcount = 0; this->Main->lists = new pizza_list *[]; } void pizza::addlist (unsigned __int16 ID, char *Name, char *Beschreibungen, unsigned __int8 PpI) { this->Main->lists[++this->Main->listcount-1] = new pizza_list; this->Main->lists[this->Main->listcount-1]->id = ID; this->Main->lists[this->Main->listcount-1]->ppi = PpI; this->Main->lists[this->Main->listcount-1]->name = new char[]; strcpy (this->Main->lists[this->Main->listcount-1]->name, Name); this->Main->lists[this->Main->listcount-1]->items = new pizza_item *[]; this->Main->lists[this->Main->listcount-1]->itemcount = 0; this->Main->lists[this->Main->listcount-1]->beschreibungen = new char[]; strcpy (this->Main->lists[this->Main->listcount-1]->beschreibungen, Beschreibungen); } void pizza::additem (unsigned __int16 ListNr, unsigned __int32 Handle, char *Name, char *Beschreibung, unsigned __int16 *Preise) { this->Main->lists[ListNr]->items[++this->Main->lists[ListNr]->itemcount-1] = new pizza_item; this->Main->lists[ListNr]->items[this->Main->lists[ListNr]->itemcount-1]->handle = Handle; this->Main->lists[ListNr]->items[this->Main->lists[ListNr]->itemcount-1]->name = new char[]; strcpy (this->Main->lists[ListNr]->items[this->Main->lists[ListNr]->itemcount-1]->name, Name); this->Main->lists[ListNr]->items[this->Main->lists[ListNr]->itemcount-1]->beschreibung = new char[]; strcpy (this->Main->lists[ListNr]->items[this->Main->lists[ListNr]->itemcount-1]->beschreibung, Beschreibung); this->Main->lists[ListNr]->items[this->Main->lists[ListNr]->itemcount-1]->preis = new unsigned __int16[this->Main->lists[ListNr]->ppi]; for (unsigned __int8 i = 0; i < this->Main->lists[ListNr]->ppi; i++) { Main->lists[ListNr]->items[Main->lists[ListNr]->itemcount-1]->preis[i] = Preise[i]; } }Ich weiß, dass es auch mit vector geht, aber ich seh keinen Vorteil darin, es anders zu machen - oder hab ich so nicht nur nen kleinen Fehler drin und es geht so gar nicht??? (glaub ich ja eigtl nicht dran, aber soll sich ja ne so anhören, als ob ich alles besser wüsste ^^)
Danke schon mal...

unskilled - da ist der Name Programm ^^
//eidt: hups - hatte da wirklich nen paar [] vergessen...
-
unskilled schrieb:
Ich weiß, dass es auch mit vector geht, aber ich seh keinen Vorteil darin, es anders zu machen
Solcher Code:
this->Main->lists[ListNr]->items[this->Main->lists[ListNr]->itemcount-1]->preis = new unsigned __int16[this->Main->lists[ListNr]->ppi];tut mir in den Augen weh. Dir nicht?
std::vector und std::string sind dafür da, dass du dich nicht um den dynamischen Speicher kümmern musst. Damit wird dein Code viel, viel einfacher und übersichtlicher.
unskilled schrieb:
oder hab ich so nicht nur nen kleinen Fehler drin und es geht so gar nicht???
Es geht so, wie du das hier anscheinend vorhast - aber dafür reichen deine Kenntnisse offenbar nicht aus. Dein Code ist voller Fehler, weil du von dynamischer Speicheralloziierung keine Ahnung hast.
Du alloziierst ein Array von Pointern ohne Größenangabe, du alloziierst einen einzelnen char und schreibst dann einen ganzen String hinein, usw.
Das, was du da vorhast, geht auch komplett ohne irgendwelche Zeiger oder new. Schmeiß den Code weg, und benutzt vector und string.
Und lass das mit dem "this->".
-
Du alloziierst ein Array von Pointern ohne Größenangabe
Dafür ist es doch eine dynamische Speicherverwaltung, damit das auch geht, oder hab ich das falsch verstanden?
btw: wenn ich die Länge statisch mache, wirds auch nicht besser...
du alloziierst einen einzelnen char und schreibst dann einen ganzen String hinein
Ja, das hatte ich wirklich vergessen

Danke...
-
unskilled schrieb:
Du alloziierst ein Array von Pointern ohne Größenangabe
Dafür ist es doch eine dynamische Speicherverwaltung, damit das auch geht, oder hab ich das falsch verstanden?
Dynamisch bedeutet nicht, dass sich das auf magische Art und Weise von selbst regelt. Dynamisch heißt hier nur, dass die Größe erst zur Laufzeit feststehen muss. Angeben musst du sie trotzdem.
Wenn du automatische Speicherverwaltung willst, nimm std::vector und std::string.
-
unskilled schrieb:
Dafür ist es doch eine dynamische Speicherverwaltung, damit das auch geht, oder hab ich das falsch verstanden?
Offensichtlich. Soll der Rechner raten wieviel Speicher Du brauchst?
Nee, dynamische Speicherverwaltung erlaubt Dir auch nur, dass Du Blöcke anfordern kannst deren Größe beim Compilieren noch nicht bekannt ist. Wunder kann C++ auch nicht vollbringen.
-
na gut : <
Danke ^^
-
unskilled schrieb:
...
//edit habs jz auch mit new gemacht, aber irgendwie hab ich da was falsch gemacht
...
Ist hier irgend ein Fehler drin?
Weil, wenn ich danach von außen darauf zugreife, kommt nen doller Zugriffsfehler - ...=>
Simon2 schrieb:
...Mach doch mal C++ ... da sparst Du Dir und uns auch Deine Folgefrage der Art "Warum bekomme ich einen SeqFault ?", "Wieso fehlen da Zeichen ?", ...
....Damit entällt jedes malloc(), realloc(), str___(), ... und alle möglicen anderen Komplikationen...."I told you so, i told you so, ...." :p :p
Sorry, ich habe keine Zeit für überflüssige Fehler.

Gruß,
Simon2.