pointer von struct array übergeben

spammich

Grünschnabel
Code:
void s_fill(row **r) {
	int n;
	row **pr;
	
	*r = new row[10]; // hier kommt nen fehler
	pr = r;
}
int main(int argc, char* argv[]) {
	row *r;
	s_fill(&r);

	// ausgabe von array

	return EXIT_SUCCESS;
}

ich möchte von der main einen zeigen auf ein struct übergeben, welches dann in der s_fill methode aus diesem zeiger einen struct array macht,.. doch irgendwie bekomme ich das net hin..

kann mir einer sagen was ich falsch mache
 
na das ist einfach nur so nen fehler der wegen ner adresse im speicher meckert,.. also etwas wo man nicht viel mit anfangen kann..
 
na das ist einfach nur so nen fehler der wegen ner adresse im speicher meckert,.. also etwas wo man nicht viel mit anfangen kann..

So leicht kann man sich das Ganze leider nicht machen.
Interessant wäre erst mal die Frage was für ein Typ ist row?
Für mich sieht der Code korrekt aus wenn ich row wie folgt definieren würde:

typedef int row;

Ist row jetzt statt eines primitiver ein komplexer Datentyp, sieht die Sache schon anders aus.
Schreib doch mal als was row definiert ist.
Ist es eine Klasse würde ich gerne die Deklaration des ctor sehen sofern dein Code nicht irgendie geheim ;-) ist ;)

Gruß René
 
void s_fill(row **r) {
int n;
row **pr;

*r = new row[10];
r[0]->nr = 10; // geht und ich kanns auch in der main auslesen
pr = r;
// wie kann ich nun via pointer werte in den array packen
}
int main(int argc, char* argv[]) {
row *r;
s_fill(&r);

cout<< r[0].nr << endl; // bsp ausgabe

return EXIT_SUCCESS;
}

ich bin nun etwas weiter gekommen und weiss nun leider nicht wie ich in s_fill via pointer einen wert in den array schreiben kann, dann pr++ mache und den nächsten wert reinschreibe... also via schleife ist klar, nur wie macht man die wertezuweisung?
 
hier der gesamte quellcode

Code:
#include <iostream>
#include <fstream>

using namespace std;

struct row {
	unsigned int nr;
	int p;
	float n;
};

void s_fill(row **r) {
	int n;
	row **pr;
	
	fstream f("daten.dat", ios::in|ios::binary);
	if (!f.good()) {
		cerr << "Cannot open input file." << endl;
	}

	//f.seekg(sizeof(int));
	f.read(reinterpret_cast<char*> (&n), sizeof(n));
	cout << n << endl;

	*r = new row[n]; 
	pr = r;
	for(int i = 0; i < n; i++) {
		if (!f.read(reinterpret_cast<char*> (&pr), sizeof(row)))
			cerr << "Cannot read from input file." << endl;
		else
			cout << "Reading values for struct ... OK (" << f.tellg() << ")" << "." << endl;
		//cout << pr->nr << endl;
		//cout << r.nr << "\t" << r.p << "\t" << r.n << endl;
		pr++;
	}
	cout << "The end of the file has been reached." << endl;
	f.close();
}

int main(int argc, char* argv[]) {
	row *r;
	s_fill(&r);

	//cout << r << endl;

	return EXIT_SUCCESS;
}
 
nach dem ich in s_fill(row **r) einen struct array mittels *r = new row[n]; erstelle erzeuge, muss ich nun feststellen das dies nicht ohne weiteres funktioniert. um dies zu überprüfen hab ich versucht mir in der main die adressen auszugeben

int main(int argc, char* argv[]) {
row *r;
s_fill(&r);

cout << r[0] << endl; // fehler an der stelle, siehe unten
cout << r[1] << endl;
}

jedoch bekomm ich dann den fehler
no match for 'operator<<' in 'std::cout << *r'

kann mir einer sagen woran das liegt
 
Leider ist so einiges schief an Deinem Projekt und das beginnt schon in main(...)

Code:
 int main(int argc, char* argv[]) {
      row *r;
      s_fill(&r);
Hier wird ein Zeiger auf eine Variable r vereinbart, aber kein Speicher alloziiert.
Quasi eine fiktive Adresse mit Daten. Dieser Pointer ist ungultig.
Selbst wenn Du jetzt Speicher alloziiert hättest geht es dann im Code weiter...

Code:
    //f.seekg(sizeof(int));
    f.read(reinterpret_cast<char*> (&n), sizeof(n));
    cout << n << endl;

    // nach diesem read steht der Dateizeiger falsch!
    // muss! zurückgesetzt werden
    f.seekg( - ( sizeof( n ) ), ios::cur ); //
Du liest von den Daten schon mal einen int Wert aus der Datei ein (hast also eine Seite im Buch aufgeschlagen), gibst die Nummer aus und willst dann von der aktuellen Position ausgehend den kompletten Datensatz einlesen - was auch funktioniert wenn noch weitere Daten verfügbar sind, aber es wird der aktuelle Datensatz und ein Teil vom nächsten Datensatz gelesen! So passt das nicht in Deine Struktur. ;)
Also muss - wenn Du schon mal im Buch vorblätterst - auch zurückgeblättert werden.

Dann das Einlesen der Daten.
Hier hat Du offensichtlich das Pointerkonzept noch nicht so ganz verstanden.

Code:
    for(int i = 0; i < n; i++) {
        if (!f.read(reinterpret_cast<char*> (&pr), sizeof(row)))
            cerr << "Cannot read from input file." << endl;
        else
Du willst in &pr einlesen und das bedeutet jetzt folgendes: An die Adresse von pr!
Oder auch so als Code geschrieben: (***pr)! da ja pr schon ein Pointer auf Pointer ist.
Die Adresse ist ja nichts anderes als ein Zeiger auf. Da Du schon Zeiger auf Zeiger hast, sagst Du damit dem Compiler: nimm mal Zeiger auf Zeiger auf Zeiger.
Rate doch mal WAS sich hinter dieser Adresse verbirgt. Keine Ahnung?
Tja der Compiler auch nicht. Das ist Speicher irgendwo ...
Konkret: Dein Zeiger **pr enthält ein Objekt, welches einen Zeiger auf ein Objekt enhält.
Einzige Bedingung: in main muss Speicher für das tatsächliche Objekt alloziiert werden.

Wie wäre der Code richtig?

Anstelle von (&pr) was gleichbedeutend mit (***pr) ist muss (*pr) hin und das Bedeutet, der Zeiger (**pr) wird genau ein mal Dereferenziert. Sprich es wird zur Adresse gegangen, die in der Adresse steht. Also wird aus Zeiger auf Zeiger nur noch der eigentliche Zeiger.


So das ganze jetzt mal komplett wie es laufen sollte, bitte schau Dir auch die Kommentare im Code an.

Code:
#include <iostream>
#include <fstream>

using namespace std;

struct row {
    unsigned int nr;
    int p;
    float n;
};

void s_fill(row **r) {
    int n;
    row **pr;
    
    fstream f("daten.dat", ios::in|ios::binary);
    if (!f.good()) {
        cerr << "Cannot open input file." << endl;
        return; //raus hier! weitermachen hat eh keinen sinn...
    }

    //f.seekg(sizeof(int));
    f.read(reinterpret_cast<char*> (&n), sizeof(n));
    cout << n << endl;
    // nach diesem read steht der Dateizeiger falsch!
    // muss! zurückgesetzt werden
    f.seekg( - ( sizeof( n ) ), ios::cur ); //


    *r = new row[n]; 
    // hier sollte *r geprüft werden ob Speicher alloziiert werden konnte!
    // ...

    pr = r;
    for(int i = 0; i < n; i++) {
        if (!f.read(reinterpret_cast<char*> (*pr), sizeof(row)))
            cerr << "Cannot read from input file." << endl;
        else
            cout << "Reading values for struct ... OK (" << f.tellg() << ")" << "." << endl;
        //cout << pr->nr << endl;
        //cout << r.nr << "\t" << r.p << "\t" << r.n << endl;
        pr++;
    }
    cout << "The end of the file has been reached." << endl;
    f.close();
}

int main(int argc, char* argv[]) {

    row *r = new row[1]; // Reservieren wir doch mal ein Objekt...
    if( NULL == r ) {
        cerr << "couldnt reserve memory for data!" << endl;
        return -1;
    }
    s_fill(&r);

    cout << r[0].nr << endl;

    // hier fehlen sämtliche delete zum Speicher abräumen...

    return EXIT_SUCCESS;
}
Ich habe den Code jetzt nur überflogen, kann sein das ich noch was übersehen habe!
Wenn es nicht klappt bitte mal Compiler nennen und die genaue(!) Fehlermeldung.

Gruß René
 
Nachtrag:

cout << r << endl;

funktioniert aus folgendem Grund nicht:
cout nimmt eigenständige Konvertierungen vor für bestimmte Datentypen (fest eingebaut in Form von Konvertierungsoperatoren), da row eine eigene Struktur von Dir selber ist, kann cout natürlich nicht wissen wie die Daten der Struktur zu behandeln sind!

Wie das geht würde hier zu weit führen, als ad hoc Lösung empfehle ich auf die Daten der Struktur aufzulösen wie in meinem Code zu sehen. Also r[0].nr als Beispiel.
Die Daten in Deiner Struktur sind "primitiver Datentypen" mit denen cout auch umgehen kann, mit selbst definierten komplexen Datentypen kann es cout nicht...

Gruß René
 
Zurück