Initialisierung eines Array schlägt fehl
-
freakC++ schrieb:
Hallo zusammen,
vielen Dank für eure Antworten.@Bisty: So besser?
for (int i=0; i<NewSize; i++) { if(i<=str.len) str.array[i]=temp[i]; else str.array[i]=0; }snip
if(i<=str.len) str.array[i]=temp[i];
Nein, Du hast da noch dieses 'letztes-Element'-Verständnisproblem.
Bei Gleichheit greift er auch noch mal zu, und pickt dann temp[str.len].
Das ist die Dimension - und die ist tabu für den Zugriff!
-
freakC++ schrieb:
So erzeuge ich eine Instanz, doch wie kann ich in einer Schleife nun a1, a2.. erzeugen.Ich habe versucht die Adressen von den Instanzen in einem anderem Array zu speichern und alles aufn Heap zu legen, doch das funzt nicht.
Da du dich ja so gegen die STL sperrst: Das ist schon der richtige Ansatz, was genau geht denn nicht?
-
Hallo,
Da du dich ja so gegen die STL sperrst
Ich sperre mich nicht gegen STL, doch möchte ich einfach das Programm so schreiben, da ich mich sowieso gerade mit dynamischen Arrays und Zeigern beschäftige und dies als eine gute Übung ansehe.
Ich habe folgendes versucht:DynArray <int> a1(10) //Anlegen einer Instanz DynArray <int> *array //Zeiger auf array array=new DynArray[10]; //So deklariere ich ein "normales" dynamisches Array, doch bezweifel ich, dass es auch hier so funzt.Das funktioniert so nicht. Da ich gerade nicht an meinem PC sitze, kann ich leider keine Fehlermeldung posten (kommt später), doch allein die zweite Zeile sieht in diesem Fall nach einem Fehler aus, da ich keinen Konstruktor aufrufe und laut meines Templates wird damit schon ein Array erstellt.. hä

Ich würde mich nochmal um einen Beispielcode freuen, der mir weiter auf die Sprünge hilft.
Vielen Dank
lg, freakC++PS.: Bitte nehmt es mir nicht übel, dass ich STL nicht nutzen will, doch möchte ich es einfach so schaffen und somit die dynamische Speicherverwaltung etc. auszschöpfen!
-
Ein allgemeines Beispiel:
template<class T> class foo{ private: T datamember; public: foo(T t): datamember(t){} T getData(){return datamember;} }; int main(){ foo<int> *array[10]; for (int i=0; i<10; ++i){ array[i]=new foo<int>(i); } for (int i=0; i<10; ++i){ cout<< array[i]->getData() <<endl; } }
-
Hallo SeppJ und natürlich auch alle anderen,
danke für dein allgemeines Beispiel. Es hat mir sehr geholfen, doch leider bleibt weiterhin ein Problem stehen. In deinem Array gibt es eine definierte Zahl, die die Anzahl der Arrays angibt. Ich bekomme diese Zahl jedoch erst zur Laufzeit. So sieht es bei mir momentan aus:DynArray<int> *sum[dif]; //Fehler for (int i=0;i<dif;i++) sum [i]= new DynArray <int> ();Die int-Variable "dif" sagt mir, wieviele Arrays benötigt werden, doch der Compiler möchte hier einen Konstantenausdruck. Kann man dieses Problem auch irgendwie lösen?
Viele Danke für deine und eure Hilfe
lg, freakC++
-
freakC++ schrieb:
Die int-Variable "dif" sagt mir, wieviele Arrays benötigt werden, doch der Compiler möchte hier einen Konstantenausdruck. Kann man dieses Problem auch irgendwie lösen?
Dann muss das eben auch wieder dynamisch sein.
-
Hallo,
mmh...müsste man dann mit doppelten Zeigern arbeiten? Gibt es da vielleicht auch so einen guten Beispielcode wie Du ihn in einem deiner letzte Posts gezeigt hast?vielen dank
lg, freakC++
-
freakC++ schrieb:
Hallo,
mmh...müsste man dann mit doppelten Zeigern arbeiten? Gibt es da vielleicht auch so einen guten Beispielcode wie Du ihn in einem deiner letzte Posts gezeigt hast?Klar:
template<class T> class foo{ private: T datamember; public: foo(T t): datamember(t){} T getData(){return datamember;} }; int main(){ int anzahl; cout<<"Anzahl Durchläufe?"<<endl; cin>>anzahl; foo<int> **array; array = new foo<int>*[anzahl]; for (int i=0; i<anzahl; ++i){ array[i]=new foo<int>(i); } for (int i=0; i<anzahl; ++i){ cout<< array[i]->getData() <<endl; } }
-
Hallo,
danke für die Antwort. Du warst schneller als ich, dennoch hier mein Beitrag, der sich jedoch noch nicht auf deine letzte Antwort bezieht, aber dennoch den Code enthält (bin selber drauf gekommen...).Ich habe noch ein bisschen herumprobiert und folgenden Code erstellt:
DynArray <int> **sum; sum = new DynArray <int> *[10]; &sum[1]->Length; //Zugriff???So kompiliert das Programm fehlerfrei, doch hatte ich zunächst beim Zugriff folgendes geschrieben:
sum[1]->Length;Hier sagt mir der Compiler: Elementfunktion muß aufgerufen oder ihre Adresse übernommen werden
Ich hab nur durchs Ausprobieren den &-Operator davor gestellt. Warum kompiliert das Programm jetzt?? Ich verstehe das nicht. Dennoch bringt mir das nichts, denn ich kann die Laenge keiner int-Variable zuweisen, obwohl die Methode Length einen einen int-Wert zurückgibt.
int zahl=&sum[1]->Length; //FehlerAuch hier erscheint der Fehler "Elementfunktion muß aufgerufen oder ihre Adresse übernommen werden".
Wie löse ich dieses Problem?
Vielen Dank
lg, freakC++
-
freakC++ schrieb:
sum[1]->Length;Ich vermisse die runden Funktionsaufrufsklammern ame Ende.
-
freakC++ schrieb:
Ich habe noch ein bisschen herumprobiert und folgenden Code erstellt:
DynArray <int> **sum; sum = new DynArray <int> *[10]; &sum[1]->Length; //Zugriff???So kompiliert das Programm fehlerfrei, doch hatte ich zunächst beim Zugriff folgendes geschrieben:
WTF?!
sum zeigt auf ein Array von 10 Zeigern, die nicht initialisiert wurden.Wozu hast Du Dir die Mühe gemacht, ein "DynArray" zu schreiben, wenn Du es nicht nutzt und wieder auf diesen Zeiger-Hickhack ausweichst?
Probier mal:
#include <map> using std::map; int main() { map<int,map<int,int> > dings; dings[23][42] = 99; }freakC++ schrieb:
sum[1]->Length;Hier sagt mir der Compiler: Elementfunktion muß aufgerufen oder ihre Adresse übernommen werden
Abgesehen davon, dass die Zeiger nicht initialisiert wurden -- warum hast Du überhaupt Doppel-Zeiger? -- habe ich keine Definition Deiner DynArray-Klasse gesehen und kann auch nicht sagen, was bei "->Length;" falsch läuft. Falls es eine Funktion sein soll, dann hast Du den "Funktions-Aufruf-Operator" vergessen: die Klammern ().
freakC++ schrieb:
Ich hab nur durchs Ausprobieren den &-Operator davor gestellt. Warum kompiliert das Programm jetzt?? Ich verstehe das nicht. Dennoch bringt mir das nichts, denn ich kann die Laenge keiner int-Variable zuweisen, obwohl die Methode Length einen einen int-Wert zurückgibt.
Aha. Dann soll "Length" also eine Elementfunktion sein. Gut, dann hast du die Klammern () vergessen, wenn Du das Ding aufrufen willst. Du darfst es aber eh nicht aufrufen, weil die Zeiger nicht initialisiert wurden.
Das & davor ist -- glaube ich -- keine legale C++ Syntax. Dein Compiler mag das akzeptieren und einen Elementfunktionszeiger zurückgeben, den man eigentlich sonst über &DynArray<int>::Length bekommt.
Gruß,
SP
-
Hallo zusammen,
sorry, dass ich mich gestern nicht gemeldet habe, doch war ich gestern in England.... Verdammt...ich habe echt vergessen die einzelne Instanz zu initialisiern und ich wundere mich über so ein komisches Zeug, das da raus kommt. Naja, so hat es dann funkioniert:int dif; DynArray <int> **sum; sum = new DynArray <int> *[dif]; for (int i=0; i<dif; i++) sum[i]= new DynArray <int> ();Es ist halt alles etwas verwirrend (ich weiß, STL wäre hier viel esser :D), da ich ein dynamisches Array erstelle, indem sich wiederum die Adresse eines Arrays befindet, das sich automatisch vergrößert (ich bin froh nicht der Computer sein zu müssen, der das alles koordiniert).
Ich probiere das jetzt mal aus und wenn es nicht klappt, dann melde ich mich wieder.
Vielen Dank für eure Hilfe
lg, freakC++
-
Hallo,
leider bleibt ein Fehler bestehen. Zunächst möchte ich jedoch die Funktionsweise des Programms noch mehr erläutern.Ich gebe zwei Zahlen ein, z.B. 5 und 10. Das Programm sucht nun für jede Zahl zwischen 5 und 10 (einschließlich 5 und 10) alle Teiler heraus und gibt sie aus. Das ist hört sich erstmal nicht so schwer an und ich habe das auch hinbekommen. Ich möchte nun, dass das Programm für jede Zahl ein Array anlegt und alle Teiler reinschreibt. In diesem Fall müssten also 6 Arrays erstellt werden (5,6,7,8,9,10). Eigentlich wird man hier denken: "Ein klarer Fall für std::vecor oder Ähnliches, doch möchte ich dieses Programm ohne die Hilfe der STL Libary erstellen. Fragt am besten nicht warum...ich habe nichts gegen STL, doch denke ich, dass es die perfekt Übung für mich ist.
Das Programm ist noch lange nicht fertig, weswegen Variablenbezeichnungen und Struktur noch zu wünschen lassen. Ich werde mich darum bald kümmern. Nun aber zum Problem: Ich habe jetzt die Arrays erfolgreich initilisiert, doch schaffe ich es nicht, etwas in die Arrays zu schreiben. Hier noch mal
der Ausschnitt des Templates, das ein vergrößerbares Array erstellt:template <typename T> class DynArray { public: DynArray() { //Konstruktor 1 str.len=0; } DynArray(int size) { //Konstruktor 2 str.len=size; str.array=new T[size]; for (int i=0; i<size; i++) str.array[i]=0; } ~DynArray() { delete [] str.array; } int Length (void) { //Methode zum Herausfinden der Arraygröße return str.len; } void NewSize (unsigned int NewSize) { //Vergrößern des Arrays T *temp=new T[str.len]; for (int i=0; i<str.len; i++) temp[i]=str.array[i]; delete [] str.array; str.array = new T[NewSize]; for (int i=0; i<NewSize; i++) { if(i<=str.len) str.array[i]=temp[i]; else str.array[i]=0; } str.len=NewSize; delete [] temp; } void Insert (unsigned int key, T value) { //Einfügen von Werten in das Array if (key > str.len || str.len==0) NewSize(key); str.array[key]=value; } ... private: struct Ar { T *array; unsigned int len; } str;Hier nun das eigentliche Programm:
void __fastcall TForm1::Button1Click(TObject *Sender) { //Eingabe von i und end. i ist die Startzahl und end die Endzahl ... arrc=0, p=0; //arrc=aktuelles Array, p=Element des aktuellen Arrays int dif=end-i+1; DynArray <int> **sum; sum = new DynArray <int> *[dif]; for (int i=0; i<dif; i++) sum[i]= new DynArray <int> (); for (i;i<=end;i++) //Die einzelnen Zahlen { sum[arrc]= new DynArray <int> (); //Bei neuer Zahl muss neues Array erstellt werden for (int k=1; k<=i;k++) //k=potentieller Teiler { if(i%k==0) //Jede Zahl wird auf Teiler überprüft { sum[arrc]->Insert(p,k); //Fehler p++; //Bei neuem Teiler wird das Element erhöht } } arrc++; p=0; //arrc wird bei jeder neuen Zahl erhöht; neue Zahl -> neues Array }Ich arbeite mit einer IDE und hier öffnet sich nur ein CPU-Fenster,d.h. es gibt keine Fehlermeldung. Wenn ich auf meine Erfahrung schließe, dann passiert dass, wenn z.B. das Array gar nicht definiert ist, oder das Element
nicht vorhanden ist bzw. das Array zu klein ist. Ich dachte, dass Template macht das alles, doch gibt es irgendwo noch einen Fehler.Könnt ihr mir helfen, den Fehler zu finden, denn dann wäre ich einen ganzen Schritt weiter.
Vielen Dank
lg, freakC++/Edit: WEnn ich folgendes schreibe:
sum[arrc]->Insert(p,k); sum[arrc]->Read(p);dann überprüfe ich, ob die Zahl an die richtige Stelle in das richtige Array geschriebenn wurde. Die Ausgaben stimmen immer, bis zu einem bestimmten Punkt, wenn das Programm abstürzt. Dieser Punkt hängt von der Anfangszahl bzw der Endzahl ab.
-
Wie war jetzt nochmal genau der Fehler?
Was ist ein CPU-Fenster?!In der Funktion NewSize löscht Du das alte Array. Im Default-Konstruktor von DynArray wird str.array aber nicht inisialisiert -> Du löscht irgendwas, was Dir nicht gehört. Dazu liest Du im zweiten Kopiervorgang in temp ein Element zu viel.
Achja, Du kannst Zeiger auch herumschubsen. Überleg mal ob Du in NewSize das ganze Array wirklich zweimal kopieren musst.
Noch ein Punkt: Debugger. Der springt im Zweifel sogar an die Stelle des Absturzes, so dass Du vage Angaben wie "ich sehe nur ein CPU-Fenster, aber keinen Fehler" präzisieren könntest.
-
Hallo zusammen
@LordJaxom: Du hast mir den entscheidenen Tipp gegeben. Ich darf nicht den Standartkonstruktor verwenden, denn sonst ist das Array nicht initilisiert. Wenn ich jedoch folgendes schreibesum[arrc]= new DynArray <int> (5);dann tritt der Fehler wieder sehr früh auf. Die 5 ist einfach so gewählt. Wenn ich jedoch das schreibe
sum[arrc]= new DynArray <int> (500);dann ist der Fehler bei mir noch nicht aufgetreten. Ich verstehe dieses verhalten nicht. Es scheint davon abzuhängen, wieviele Arrays zu Beginn initilisiert werden. Wenn ich aber irgendwann mal mit riesigen Zahlen arbeite, dann weiß ich nicht, ob die 500 noch "reicht". Wie kann man dieses Verhalten erklären und den Fehler ein für alle entfernen.
Ich verwende den C++ Builder 6 als IDE. Dort öffnet sich ein Fenster mit der Überschrift "CPU" und mir werden irgendwelche Hexadezimal Zahlen angezeigt. Ich weiß ja selber nicht was das ist, aber eine präzise Fehlermeldung gibt es nicht.
Vielen, vielen Dank
lg, frealC++
-
Hast Du den anderen Hinweis (im Array temp eins zuviel gelesen) auch verfolgt?
Das CPU-Fenster im Borland Builder deutet darauf hin, dass der den Absturz erkennt und versucht, Dir die genaueren Umstände mitzuteilen. An dieser Stelle kannst Du normalerweise über "Aufruflisten" oder "Stacktraces" auch an die Stelle im Programm gelangen, die den Absturz verursacht. Das wäre jedenfalls bei anderen IDEs üblich. Wie das genau bei Borland funktioniert, kann ich Dir aber nicht sagen, da ich Borland nicht verwende.
-
int dif=end-i+1;
Notfalls hilf Dir durch Einsetzen kleinstmöglicher Zahlen.
z.B. 1 für i und 2 für end.
dif = 2-1+1; macht 2!
Ist das wirklich die Differenz zwischen 2 und 1?Manchmal hat man einfach ein dämliches Grundproblem zu kapieren, daß man 23 Stück Brot kriegt, wenn man 22 mal schneidet - oder so

-
Hallo,
stimmt, daran habe ich noch gar nicht gedacht. Ich werde mir das nochmal genauer angucken!! Dankelg, freakC++
-
Halte durch - nur Fehler bringen einen wirklich voran
