arrayübergabe / array kopieren
-
Hallo Leute,
folgendes Problem:
ich habe auf der einen seite folgenden code:unsigned char *imgData = new unsigned char[m_size]; fread(imgData,m_size,1,f); m_bmp->setImgData(imgData); //delete[] imgData;das array soll in der methode setImgDate weiterübergeben werden an ein objekt einer anderen klasse. dort hab ich als membervariable ebenfalls ein Array zunächst mal in der headerdatei mit unsigned char* m_imgData;
jetzt soll das parameterarray auf dem m_imgData array kopiert werden eben in der methode
bool CPixelFormat_24bit::setImgData(unsigned char *imgData) { m_imgData = imgData; return true; }leider funktioniert das ganze nicht und spuckt mir einen segmenation fault aus....
kann mir jemand weiterhelfen?
-
Du setzt nur einen Zeiger. Danach zeigen mehrere Zeiger auf das dynamische Array.
Was du suchst, ist die STL-Funktion
std::copy(). Allerdings würde ich dir gleich raten, zu einem Container wiestd::vectorzu wechseln, damit bist du grundsätzlich flexibler und kannst Kopien ganz einfach und intuitiv durchführen. Das Gleiche gilt fürs Anhängen und Entfernen einzelner Elemente, Leeren des Containers, und so weiter. Die ganze Speicherverwaltung wird dir abgenommen. Schau mal unter www.cplusplus.com.Wo wir gerade bei Speicherverwaltung sind: Hast du daran gedacht, dein dynamisches Array mit
delete[]wieder freizugeben?
-
Nexus schrieb:
Du setzt nur einen Zeiger. Danach zeigen mehrere Zeiger auf das dynamische Array.
wieso meinst du?
in der ersten klasse erzeug ich einen zeiger:unsigned char *imgData = new unsigned char[m_size]; fread(imgData,m_size,1,f); m_bmp->setImgData(imgData);das array wird an m_bmp->setImgData(..) übergeben.
in der anderen klasse hab ich im headerfile auch einen zeiger definiert
Header:... .. private: unsigned char* m_imgData; ... ..und das array soll einfach kopiert werden...
bool CPixelFormat_24bit::setImgData(unsigned char *imgData) { memcpy(imgData, m_imgData, sizeof(imgData)); //hab hier mal die varieante mit memcpy()...geht auch nicht.. return true; }wo zeigen mehrere zeiger auf was?

-
m_imgData = imgData;In dieser Zeile weist du einen Zeiger einem anderen zu. Danach zeigen mehrere Zeiger auf deinen Speicherbereich von
unsigned chars.Du solltest auch nicht
memcpy()verwenden. Schau doch mal, welche Funktionen und Klassen ich angesprochen habe.
-
nagut, dann wäre das mit std::copy irgendwie so-->
copy ( imgData,imgData + sizeof(imgData), m_imgData );wiederrum compilierbar aber nicht lauffähig ..liegt wahrscheinlich wieder am problem mit den pointern? muss ich die dinger nicht alle dereferenzieren? aber dann mäckert der compiler..
-
sizeof(imgData)gibt dir die Grösse des Typen zurück. In diesem Falle vonunsigned char*, und die ist meistens 4 Byte.Übergib die Grösse des Arrays als zusätzlichen Parameter. Würdest du STL-Container einsetzen, hättest du alle diese Probleme nicht...
-
Nexus schrieb:
Übergib die Grösse des Arrays als zusätzlichen Parameter. Würdest du STL-Container einsetzen, hättest du alle diese Probleme nicht...
ja das glaube ich dir, allerdings möchte ich jetzt nich meinen gesammten code umschreiben müssen wegen dieser (kleinen) sache. mich interessiert im moment nur folgendes: warum zum teufel bekomm ich andauernd segmentation fault...
size übergebe ich nun als parameter mit und:copy ( imgData,imgData, size, m_imgData );das hält mich jetzt schon fast 2 stunden auf

-
cryps schrieb:
copy ( imgData,imgData, size, m_imgData );Kannst du ein Stück kompilierbaren Code zeigen, am besten mit dem Kontext in der Funktion und der Erstellung des ursprünglichen Arrays?
-
--
-
--
-
okay...
nach langem rumprobieren bin ich jetzt zwar schon recht verzweifelt.. aufgeben tu ich trotzdem noch nicht...kann es sein, dass man in c++ eine Membervariable nich aus jeder Methode der klasse zu beliebigem zeitpunkt beschreiben darf?
anders kann ichs mir nicht mehr erklären....hmm also zB.folgendes szenario:
ich habe eine klasse A die erzeuge ein objekt der Klasse B. in der Klasse B gibt es eine Membervariable int value; dieses Objekt ist in der Klasse A mittels Komposition eingebettet.
nun übergibt eine Methode der KLasse A einen integer als parameter an dieses Objekt (bzw. an eine Methode des Objekts). dieser Übergebene Wert wird nun der Membervariable von Klasse B zugewiesen.Kann es sein dass sowas nicht geht?
A.h:
class A{ public: A(); virtual ~A); void setValue(); private: B* OBJB; };Klasse A:
A::A(){ B = new B(); } A::~A(){} void A::setValue() { B->setValue(50); }B.h:
class B{ public: B(); virtual ~B(); void setValue(int b); private: int value; };Klasse B
B::B(){} B::~B{} B::setValue(int b) { this->value = b; // SEGMENTATION FAULT }
-
Ich würde mal so spontan raten und sagen, dass in der Klasse A der Zeiger auf B ungültig ist. Womöglich löschst du das Objekt irgendwo und greifst später dann trotzdem darauf zu.
Grundsätzlich kann ich aber fast nur das sagen, was Nexus schon gesagt hat:
Kannst du ein Stück kompilierbaren Code zeigen, welcher den Fehler reproduziert und dazu kurz gehalten ist?(hab mir erlaubt, das Entscheidende noch deutlicher hervorzuheben :))
Grüssli
-
cryps schrieb:
ja das glaube ich dir, allerdings möchte ich jetzt nich meinen gesammten code umschreiben müssen wegen dieser (kleinen) sache.
So klein scheint die Sache für Dich ja nicht zu sein. Sonst würde es Dir nicht solche Schwierigkeiten bereiten.
Vermutlich wärst Du schon lange fertig, wenn Du einen std::vetor benutzt hättest. Das man durch die Benutzung eines Vektors an einer Stelle den gesamten restlichen Code umschreiben muss ist auch ziemlich unwahrscheinlich.
-
B::B(){}
B::~B{}B::setValue(int b) {
this->value = b; // SEGMENTATION FAULT
}Kommt immer drauf an, wann und wo du dieses Gedöns aufrufst.
Weiterhin ist in deiner Klasse A, die Klasse B gar nicht bekannt, weder durch ein vernünftiges include, noch über eine Vorwärtsdeklaration(eventuell hast du es nur nich mit hingeschrieben).
So jetzt kommt auf das drauf an, was ich ganz oben schon geschrieben habe. Natürlich bist wärst du dir geholfen wenn du die Ratschläge der anderen annehmen würdest,std::vectorund Konsorten machen die Sache wesentlich einfacherer
-
Danke für die vielen Antworten...
Ich entschuldige mich dafür, dass es vielleicht etwas unverschämt rüber gekommen ist, dass ich eure Ratschläge nicht "annimm"... ich bin im gegenteil sehr dankbar dass es diese hilfe gibt....:)
ich glaube ich habe meinen Fehler bereits gefunden... Der Segmentation Fault Error erschien schlicht und einfach deshalb weil in meinem Objektechaos dieses angesprochene Objekt noch gar nicht existierte....
Nichts desto trotz werde ich mich heute noch dazu setzen und das ganze wahrscheinlich doch mit std::vector umsetzen. wer weiß was ich später noch alles anfange .... da wäre es vielleicht doch gut nicht mit char* arrays rumzuhantieren.....
funktioniert das ganze gleich wie mit arrays? bzw. kann ich den vector auch wie zuvor einfach so mit fread füllen?vector<char> imgData; fread(&imgData,m_size,1,f);liebe grüsse
-
cryps schrieb:
funktioniert das ganze gleich wie mit arrays? bzw. kann ich den vector auch wie zuvor einfach so mit fread füllen?
Wenn du C++ einsetzen willst, dann setze gleich vollständig C++ ein. Nimm keine C Funktionen für die Ein- und Ausgabe. In C++ hat man dafür Streams:
http://www.cplusplus.com/reference/iostream/Es kommt ganz darauf an, was du machen willst beim Auslesen des Files. Erst dann kann ich dir sagen, wie du dies einsetzen kannst.
Grüssli
-
Dravere schrieb:
Es kommt ganz darauf an, was du machen willst beim Auslesen des Files. Erst dann kann ich dir sagen, wie du dies einsetzen kannst.
Grüssli
Ich lese ein bmp file im binären modus ein...das funktioniert ganz gut mit fread... das fread bei diesem code liest die bildinformationen (nicht den header) der größe m_size ein und früher hab ich das eben in ein char* array namens imgData hineingespeichert... funktioniert das auch mit dem vector jetzt?
ich kanns atm nicht ausprobieren....lg
vector<char> imgData; fread(&imgData,m_size,1,f);
-
cryps schrieb:
Ich lese ein bmp file im binären modus ein...das funktioniert ganz gut mit fread... das fread bei diesem code liest die bildinformationen (nicht den header) der größe m_size ein und früher hab ich das eben in ein char* array namens imgData hineingespeichert... funktioniert das auch mit dem vector jetzt?
ich kanns atm nicht ausprobieren....Nein, das geht so nicht. Du musst den Vector zuerst anweisen Speicher zu reservieren. Dann musst du einen Zeiger auf den internen Speicher der fread Funktion übergeben und kannst in den Speicherbereich lesen.
Allerdings wundert es mich, dass dies früher bei dir funktioniert haben soll, denn du benutzt die fread Funktion sowieso falsch, auch ohnestd::vector.
http://www.cplusplus.com/reference/clibrary/cstdio/fread/Du hast die beiden mittleren Parameter meiner Meinung nach vertauscht.
Aber unter C++ würde ich das sowieso über einen std::ifstream machen. Also pseudomässig etwa so:
#include <vector> #include <fstream> int main() { std::ifstream file("file.bmp", std::ios::binary | std::ios::in); // ... // Vektor erstellen und size Speicher reservieren. std::vector<char> imgData(size); // Zeiger auf erstes Element des zusammenhängenden Speicher holen // und dann in dieses Array size chars einlesen. file.read(&imgData[0], size); // ... return 0; }Allerdings empfiehlt es sich wohl schon eher, dass du zuerst irgendwo ein Tutorial oder Buch zu C++ liest. Wenn du all diese Dinge noch nicht kennst, dann programmierst du ja eher C als C++.
Grüssli