Effizientes kopieren von Daten im Speicher

RuFFnEcK

Erfahrenes Mitglied
Hallo Forum,

ich hab memcpy schon ewig nicht mehr benutzt und als ich es benutzt habe, habe ich mir wohl nie weiter Gedanken gemacht, aber:

1. Wenn ich z.B. eine beliebige Struktur mit memcpy von einem Zeiger auf den nächsten kopieren, dann muss ich doch vor dem Kopieren Speicher allozieren, oder****?

2. So wenn jetzt die zu kopierende Struktur std::vector enthält, dann muss ich jedes mal schauen wie groß die Struktur momentan ist und am besten wohl jedes mal den alten zeiger löschen und neuen Speicher allozieren... Ist das richtig?

3. Beim Schreiben fällt mir auf, dass der Vector doch im Speicher verteilt war, oder?

4. Dann könnte doch theoretisch memcpy gar keine Vectoren kopieren, oder?

Verdammt Fragen über Fragen, ich nummerier die jetzt noch^^

Somit ergibt sich die 4.te Frage zur wichtigsten...

Viele Grüße
RuFF
 
Hi.

Grundsätzlich können C++ Objekte nicht mit C Speicherverwaltungsfunktionen gehandhabt werden.

zu 2) ein std::vector hat immer die gleiche Größe (sizeof(std::vector<T>) ist konstant). Das gleiche trifft auf jede andere Struktur zu.

Gruß
 
Erstmal vielen Dank an euch beide.

Ich hatte eigentlich schon geantwortet, aber wohl vergessen auf Antworten zu klicken, verdammt ^^

Frage zu 1. Wenn ich eine einfache Struktur habe und die kopieren will, dann kann ich ja memcpy verwenden, da reine C Struktur. Dann meine Frage, reicht ein memset um Speicher zu allozieren (Klassenmember, kein Pointer...)?

Frage zu 2. Welche Größe liefert mir denn sizeof(std::vector<T>)? Dann ist das ja nur Abhängig vom Datentypen und nicht von der eigentlichen Gößr. Weil der kann ja im Speicher nicht en gleichen Speicher belegen, wenn ich von mir aus 100 000 integer mit push_back in den vector knalle, oder?

Zu 3. Ja ich errinner mich, das war ja einer der Gründe warum der vector so langsam war. Es müssen ja eventuell, wenn neue Daten (random acces iterator) an eine beliebige Stelle eingefügt werden, die restlichen Daten verschoben werden und wenn der Speicherblock net ausreicht muss alles an eine Stelle verschoben wo alles zusammenhängend hin passt...

Ich Danke euch beiden!
 
Erstmal vielen Dank an euch beide.

Ich hatte eigentlich schon geantwortet, aber wohl vergessen auf Antworten zu klicken, verdammt ^^

Frage zu 1. Wenn ich eine einfache Struktur habe und die kopieren will, dann kann ich ja memcpy verwenden, da reine C Struktur. Dann meine Frage, reicht ein memset um Speicher zu allozieren (Klassenmember, kein Pointer...)?
memset alloziert keinen Speicher. Ich verstehe die Frage irgendwie nicht... ?
Frage zu 2. Welche Größe liefert mir denn sizeof(std::vector<T>)? Dann ist das ja nur Abhängig vom Datentypen und nicht von der eigentlichen Gößr. Weil der kann ja im Speicher nicht en gleichen Speicher belegen, wenn ich von mir aus 100 000 integer mit push_back in den vector knalle, oder?
Im Grunde besteht ein Vektor nur aus ein paar Attributen:
C++:
class vector<T> {
  T* m_data;
  size_type m_capacity;
  size_type m_size;
};
D.h. wenn sizeof(void*) == 4 und sizeof(size_type) == 4 ist, dann ist ein std::vector 3*4 Byte groß. Je nach Implementierung.

Die Daten die du da mit push_back speicherst, ändern nichts an der Größe der Struktur.

Gruß
 
Die Frage ist auch komisch formuliert und eigentlich weiß ich auch dass memset keinen Speicher alloziert^^

Also ich machs einfach mit Code und eine kleine Erklärung.
Ich habe ein Projekt übernommen und der Kollege der das implementiert hatte, war nicht sonderlich fit. Nur läuft das Ding schon seit Jahren, darum habe ich die Implementierung als korrekt angenommen...

Also der macht folgendes:

Vorab ein paar Struktur definitionen:

Code:
typedef struct {
	int err_no;
	int err_time;
} flthist_entry_t;

typedef	struct {
	flthist_entry_t data[10];
} flthist_t;


Klassendeklaration:
Code:
class CStatusView : public CFormView
{

...
private:

	flthist_t m_OldFlthist;
...

Dann wird im Konstruktor einmal
Code:
memset(&m_OldFlthist, 0x00, sizeof(m_OldFlthist));
aufgerufen.

Dann wird ein Timer gestartet der alle 100 ms folgendes macht:

Code:
void CStatusView::OnTimer(UINT nIDEvent) 
{
   ...
   if (memcmp(&pDoc->m_DriveActVal.fhtFlthist, &m_OldFlthist,
		sizeof(pDoc->m_DriveActVal.fhtFlthist)) || m_bFirst)
   {
        ...

	memcpy(&m_OldFlthist, &pDoc->m_DriveActVal.fhtFlthist,
			sizeof(pDoc->m_DriveActVal.fhtFlthist));
   }

Sooo nachdem ich die Informationen isoliert habe, fällt mir auch auf, dass da überhaupt kein dynamischer Speicher alloziert werden muss und das ganze so wie es ist korrekt ist^^
Habs aber getz stehen lassen, weil das soviel Arbeit war und viell. hilfts ja jemandem^^

Ich danke euch nochmal für die Erklärungen!


Viele Grüße
RuFF
 
Zurück