Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Dynamisches Array aus Methode heraus füllen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
09.11.2008, 12:40 Uhr
~shinji
Gast


Hallo!

Ich habe momentan einen Knoten im Gehirn, weil ich mit meinem kleinen Problem nicht weiter komme.

Und zwar möchte ich innerhalb der main() eine Methode aufrufen die zweierlei machen soll.

1) Daten in ein Arrray schreiben, wobei ich der Methode den Pointer auf den Speicher übergebe. Nach Beendigung der Methode soll das Array noch im Speicher stehen.

2) Einen Rückgabewert liefern, der die Anzahl der Arrayelemente angibt.

Das alles wird kompliziert dadurch, da ich vor dem Aufruf der Methode nicht die Göße des Arrays kenne. Es handelt sich also um ein dynamisches Array. So ungefähr sieht der (bereinigte, ohne Klassen) Code aus:


C++:
int main()
{
    int *daten;
    int eintraege;

    eintraege = getData(daten);
    printf("%d - %d\n", eintraege, daten[0]); // Ergibt nur Müll bzw. Segmantation Fault
    free(daten);
    return 0;
}




C++:
int getData(daten)
{
    int *tmp=NULL // Temporaeres Array
    int rows; // Anzahl der Daten
    int i; //Hilfsvariable

    rows = getRows();

    tmp = new *int[rows];

    // Ganz viel Voodoo der das tmp-Array fuellt

    for (i=0; i<rows; i++) printf("%d", tmp[i]); // Gibt den richtigen Wert aus - z.B. 100

    daten = calloc(rows, sizeof(int)); // Speicher reservieren fuer Rueckgabe
    memcpy( daten, tmp, rows ); // Array umkopieren

    for (i=0; i<rows; i++) printf("%d", daten[i]); // Gibt die Werte aus tmp aus.

    return rows;
}



Sorry wenn ich etwas vergessen habe, aber ich muss den Code gerade aus dem Kopf heraus aufschreiben. Mein Problem ist halt das "daten" außerhalb der Methode nur Müll enthält. So als wäre der Speicher nie reserviert bzw. nie mit Daten gefüllt worden.

Der einzige Lösungsvorschlag den ich bisher dazu gehört hatte war, dass ich doch für "daten" einfach ein Array mit der maximal vorstellbaren Größe fest anlegen soll. Also einfach

int daten[30000];

oder so was. Das finde ich aber ziemlich bescheiden da das Array durchaus auch mal nur einen Eintrag haben kann.

Wo liegt denn mein Denkfehler?

Vielen Dank!

Gruß
Thorsten
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
09.11.2008, 15:14 Uhr
0xdeadbeef
Gott
(Operator)



C++:
int getData(daten)


sollte dir jeder anständige C++-Compiler um die Ohren hauen, daten braucht einen Typ. In diesem Fall willst du den Zeiger in der Funktion ändern, dementsprechend musst du ihn als Referenz übergeben:

C++:
int getDaten(int *&daten)


Ansonsten ist die Verwendung von calloc in C++-Programmen ausgesprochen unschön, insbesondere, wenn der Speicherbereich nachher von anderem Code besessen wird - der erwartet im Zweifel nämlich, ihn mit delete[] wieder freigeben zu müssen, nicht mit free(). Oh, und du gibst tmp niemals frei, deine Funktion leckt also Speicher.

In dem Zusammenhang - es wäre wahrscheinlich einfacher, statt dieses ganzen Aufrisses einfach einen std::vector<int> zu benutzen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
09.11.2008, 16:39 Uhr
~shinji
Gast



Zitat von 0xdeadbeef:

sollte dir jeder anständige C++-Compiler um die Ohren hauen, daten braucht einen Typ.



Ja, ich weiß. Das hab ich eben übersehen beim Schreiben. Da steht ja auch so was wie


C++:
int getDaten(int *daten)



Muss denn da ein


C++:
int getDaten(int *&daten)



Hmmmmm....


Zitat von 0xdeadbeef:
Ansonsten ist die Verwendung von calloc in C++-Programmen ausgesprochen unschön, insbesondere, wenn der Speicherbereich nachher von anderem Code besessen wird.



Wie geht das denn dann anders in C++?


Zitat von 0xdeadbeef:
Oh, und du gibst tmp niemals frei, deine Funktion leckt also Speicher.


Ok.... da steht eigentlich noch ein


C++:
delete[] tmp
tmp=NULL;




Zitat von 0xdeadbeef:
In dem Zusammenhang - es wäre wahrscheinlich einfacher, statt dieses ganzen Aufrisses einfach einen std::vector<int> zu benutzen.


Hmmm.... damit habe ich noch nie was gemacht. Hab da mal kurz reingeguckt und war der Meinung das ich es nicht gebrauchen kann.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
09.11.2008, 16:47 Uhr
0xdeadbeef
Gott
(Operator)


In C++ benutzt man halt new und delete bzw. new[] und delete[]. Und mir scheint ein Vektor ziemlich genau das zu sein, was du haben willst - oder gleich ein output-Iterator, wenn man's schön c++ig haben will.

Mit dem Vektor:

C++:
#include <vector>

void getDaten(std::vector<int> &daten) {
  int rows = getRows();

  daten.resize(rows);

  // Kram in daten reinschreiben, nachher ist daten.size() == rows
}

int main() {
  std::vector<int> daten;

  getDaten(daten);
}


Oder mit Iterator:

C++:
#include <iterator>
#include <vector>

template<typename oiter_t> int getDaten(oiter_t dest) {
  while(weiteres_zeug_vorhanden()) {
    *dest = zeug_holen();
    ++dest;
  }
}

int main() {
  std::vector<int> daten;

  getDaten(std::back_inserter(daten));
}


Letztere Variante hat den Vorteil, dass du den Kram quasi überall hin schreiben kannst, z.B.

C++:
getDaten(std::ostream_iterator<int>(std::cout, "\n"));


...was den Kram dann untereinander auf der Konsole ausgäbe.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: