Frage zu Programmieraufgabe
-
Du hast Speicher für 0 Elemente reserviert. Das geht schief, wenn du in irgendeiner Weise da drauf zugreifst.
Ehrlich gesagt: Dein Code ist ein Verbrechen gegen alle Prinzipien sauberer Programmierung und gegen C++. Derjenige der dir das so beigebracht hat, gehört erschossen.
-
Wenn du damit fertig bist, sollte das Ganze dann noch vernünftig implementiert werden, d.h.
- ohne globale Variablen
- mit C++-Headern (stdlib.h gehört nicht dazu)
- ggf. mit einer Klasse statt haufenweise freien Funktionen zu den Variablen.Wenn das, was du da als allererstes gepostet hast, tatsächlich Vorgabe eures Lehrers/Dozenten/Profs ist, hast du natürlich ein Problem - dann macht nämlich schon diese Vorgabe sauberen Code schwierig bis unmöglich.
-
Hallo, das Skelett wurde uns vorgegeben, sprich wir sollen globale Variablen machen, stdlib.h wurde bereits von vornherein eingeführt ect...
Wegen dem reservierten Speicher: Ich dachte, wenn ich anschliessend inizialisiere, reserviert der mir auch mehr Platz?
Der Fehler ist folgender:
[code] /*** *void operator delete() - delete a block in the debug heap * *Purpose: * Deletes any type of block. * *Entry: * void *pUserData - pointer to a (user portion) of memory block in the * debug heap * *Return: * <void> * *******************************************************************************/ void operator delete( void *pUserData ) { _CrtMemBlockHeader * pHead; RTCCALLBACK(_RTC_Free_hook, (pUserData, 0)); if (pUserData == NULL) return; _mlock(_HEAP_LOCK); /* block other threads */ __TRY /* get a pointer to memory block header */ pHead = pHdr(pUserData); /* verify block type */ _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); _free_dbg( pUserData, pHead->nBlockUse ); __FINALLY _munlock(_HEAP_LOCK); /* release other threads */ __END_TRY_FINALLY return; } #endif /* _DEBUG */
-
tschabos schrieb:
Wegen dem reservierten Speicher: Ich dachte, wenn ich anschliessend inizialisiere, reserviert der mir auch mehr Platz?
Falsch gedacht. Wenn du machst
int a = 1; int b = a; a = 5;Dann ist b danach schließlich auch nicht 5. (Ich hoffe mal, dass du das auch so siehst)
Du musst also Nachreservieren und Umschichten, wenn du den Stapel vergrößern willst. Du begibst dich hier auf das sehr rutschige Feld der manuellen Speicherverwaltung (etwas, was man in C++ übrigens nie braucht, viel Spaß beim sinnlosen Lernen!), wo selbst geübte Programmierer schnell schwer zu findende und Fehler einbauen, die man zudem immer erst dann auffallen, wenn man das Programm jemandem vorführt (das einzig definierte an undefiniertem Verhalten
).
-
Die Vorgabe des Framewort ist, wie du ja nun mitbekommen hast, ziemlich Schwachsinnig. Ohne Verbrechen gegen saubere Programmierung ist da nichts zu implementieren (Zudem hat dies mit C++ eigentlich wenig zu tun, außer die Verwendung von cout und Co ist dies vom Aufbau her ein C-Programm; In C++ Programmiert man jedenfalls Anders).
Aber wenn man dieses Framework schon nutzen muss, so kann man dennoch wesentlich sauberer als dein Versuch vorgehen. Zudem ist mir vieles in deinem Programm völlig unverständlich.
Du benutzt einerseits ein Struct wo du Daten zu einem Stack hälst, aber den eigenen Stack und einen Zähler behandelst du davon unabhängig? Des weiteren solltest du dich auf deutsch oder englisch einigen, und nicht ein Mischmasch verwenden.
Ich würde dir vorschlagen dann wenigstens die Informationen zu dem Stapel auch komplett in der Struktur zu halten. Zudem solltest du nicht ständig den Zeiger mit dem du das Array verwaltest hin und her bewegen, sondern lieber einen separaten Zeiger (falls nötig) auf ein aktuelles Element verwalten.
Nach meiner Meinung benötigst du ohnehin weniger Variablen. Dazu aber eine die grundsätzliche Frage: Willst du den eigentlichen Stapel bei jedem push/pop komplett neu generieren, oder willst du nur bei einem push ihn bei Bedarf vergrößern?
Im letzteren Fall würde ich drei Werte halten:
a) Den Zeiger auf das Array
b) Die Größe (Wie groß ist das reservierte Array? Alternativ einen Zeiger auf das Letzte Element*)
c) Die Position (Wo im Array befindet sich das "oberste" Element? Alternativ einen Zeiger auf das aktuelle Element*)
* Ich wäre aber eher für den Zahlenwert, da dies unabhängiger von a ist.(Im Ersteren Fall wäre Größe und Position immer identisch).
a Würde ich nur dann anfassen wenn du ein neues Array erzeugst.
Einen leeren Stack würde ich auch nicht durch new allozieren, sondern mit 0/NULL definieren.
-
Hallo, vielen Dank für die hilfreichen Antworten.
Ok, versuche einmal mehr in die Struktur zu nehmen.
-
So, habe nun noch versucht die Zählervariable in die struct zu nehmen, dann habe ich noch eine Variable eliminiert. Ich weiss aber immer noch nicht richtig, wie ich das mit dem Pointerarray machen soll. Der Pointer muss ja immer auf das oberste Element zeigen, um es abzurufen. Daher sollte doch der Pointer auch verändert werden, wenn die Arraygrösse nicht ändert?
Und wie würdet ihr das machen wegen der Arraygrösse mit dem Pointer?[code] #include <stdlib.h> #include <iostream> #include <string> using namespace std; //**************************************************************************************************************************************** struct stack{ //Definiert ein Struct int size_array; //Arraygroesse int position; //Stapelgroesse (pointer zeigt auf oberstes Element) }stack_define; int *dynamic_array = new int[stack_define.size_array]; //Dies ist das dynamsche Array //**************************************************************************************************************************************** void init() { //inizialisiert den struct dynamic_stapel stack_define.size_array = 2; stack_define.position =0; } //**************************************************************************************************************************************** int pop(){ // nimmt das oberste Element vom Stapel und loescht es, ebenfalls wird der Zeiger auf das Element darunter gerichtet if (stack_define.position > 0){ // Wenn es mindestens 1 Element gibt stack_define.position = stack_define.position -1;// Elemente nehmen ab dynamic_array = dynamic_array -1; } return 0; //Soll zeigen, dass der Stapel um 1 Element abnimmt } //**************************************************************************************************************************************** void push(int element){ //legt ein neues Element oben auf den Stappel stack_define.position = stack_define.position + 1; // die Anzahl Elemente nehmen zu if (stack_define.position > stack_define.size_array){ // Wenn es mehr Elemente gibt als das Array gross ist int copy_array[stack_define.position]; //erstellt ein Zwischenspeicherarray for (int i=0 ; i<stack_define.position ;i++){ //Umkupieren der Elemente copy_array[i] = dynamic_array[i]; } delete [] dynamic_array; //dynamic array Elemente werden geloescht while (stack_define.position > stack_define.size_array){ //Dann wird die Arraygroesse so lange verdoppelt, bis das Array groesser als die Anzahl Elemente ist. stack_define.size_array = 2*(stack_define.size_array); } for (int i=0 ; i<stack_define.position; i++){ //Nun werden die Copy Elemente wieder in das nun groessere Array kopiert dynamic_array[i] = copy_array[i]; } } dynamic_array = dynamic_array +1; *dynamic_array = element; //Dem obersten Element wird der Wert von der Einageb "element" zugeordnet } //**************************************************************************************************************************************** int size() { //gibt die groesse des Stapels an return stack_define.position; } //**************************************************************************************************************************************** void clear() { //Loescht den ganzen Stapel delete [] dynamic_array; } //**************************************************************************************************************************************** //Dieses Funktion implementiert eine Testumgebung f�r den Stack void test() { cout << "The program has been startet without any arguments." << endl; cout << "The program enters the stack test mode:" << endl; cout << "Enter one of the commands: push, pop, end" << endl; string command; do{ cin >> command; if (command == "pop"){ cout << pop() << endl; } else if (command == "push"){ cout << "element?"; int elementToPush; cin >> elementToPush; push(elementToPush); } else if(command == "end"){ } else {cout << "command not recognised"<< endl;}; }while(command != "end"); } //**************************************************************************************************************************************** int main(int argc, char * argv[]){ init(); test(); cout << "The stacksize is: "; //Gibt die groesse vom Stapel aus cout << stack_define.position; cout << "\n" << "The top element is: "; //gibt das oberste Element aus cout << *dynamic_array; clear(); return 0; }
-
SeppJ schrieb:
Du begibst dich hier auf das sehr rutschige Feld der manuellen Speicherverwaltung
: richtig
SeppJ schrieb:
etwas, was man in C++ übrigens nie braucht
: falsch
SeppJ schrieb:
wo selbst geübte Programmierer schnell schwer zu findende und Fehler einbauen
: richtig
-
EOP schrieb:
SeppJ schrieb:
Du begibst dich hier auf das sehr rutschige Feld der manuellen Speicherverwaltung
: richtig
SeppJ schrieb:
etwas, was man in C++ übrigens nie braucht
: falsch
Ja und nein...
Was man in C++ selten braucht, oder zumindest kapselt bzw. die Verwaltung abgibt (z.B. unique_ptr...).
-
tschabos schrieb:
...
Kleinen Tip für den Anfang. Die einzige globale variable ist dabei stack.
#include <stdlib.h> #include <iostream> #include <string> using namespace std; struct stackdata { int * array; // Das Array, das die Daten hält int size; // Die Größe des Arrays int position; // Die aktuelle Position im Array } stack; void init() { // Noch sind keine Daten vorhanden // (Wie du hier auf Größe 2 gekommen bist ist mir unklar) stack.array = NULL; // Initial noch kein Array, da Größe < 1... stack.size = 0; stack.position = 0; } //...