2010-01-29 11 views
19
class Help 
{ 
public: 
     Help(); 
     ~Help(); 

     typedef std::set<string> Terms; 
     typedef std::map<string, std::pair<int,Terms> > TermMap; 
     typedef std::multimap<int, string, greater<int> > TermsMap; 

private: 

     TermMap terms; 
     TermsMap termsMap; 
}; 

Wie können wir den Speicher verwendet (in Bytes) von den Objekten term und termsMap finden. Haben wir eine Bibliothek?wie der Speicher durch ein beliebiges Objekt verwendet finden

Antwort

-1

der sizeof() Operator sollte es tun:

size_t bytes = sizeof(Help::TermMap); 
+5

'sizeof' ist ein Operator, keine Funktion. –

+1

@Carl Norum: Richtig du bist. Danke für die Erinnerung! –

+1

Hmm. Dies scheint aus zwei Gründen nicht zu funktionieren: Die Mitglieder sind privat, und Sie dürfen nicht die Größe einer nicht statischen Mitgliedsvariablen annehmen. Interessant! –

1

Wenn Sie sich für den eigentlichen Speicherblock, der numerische Wert eines Zeigers auf sie es sein sollte suchen. (Dann fügen Sie einfach die Anzahl der Bytes hinzu und Sie haben das Ende des Blocks).

12

Wenn Sie nach der vollen Speichernutzung eines Objekts suchen, kann dies in C++ im Allgemeinen nicht gelöst werden. Während wir die Größe einer Instanz über sizeof() ermitteln können, kann das Objekt Speicher immer dynamisch nach Bedarf zuweisen .

Wenn Sie, wie groß das einzelne Element in einem Behälter sind herausfinden können, Sie eine untere Schranke bekommen:

size = sizeof(map<type>) + sum_of_element_sizes; 

Beachten Sie aber, dass die Behälter noch zusätzlichen Speicher als Implementierungsdetail zuordnen kann und Bei Containern wie vector und string müssen Sie nach dem allocated size suchen.

+0

Betrachten Sie das als grobe Unterschätzung. In vielen Fällen, wie bei Karten, muss die STL andere Dinge enthalten (Karte ist ein ausgewogener Baum, also benötigt sie mindestens drei Zeiger (links, rechts, Eltern - Elternteil, um schnelles Iterator - Transversal zu garantieren) und eine Art, Informationen für zu halten die Balance invariant, wahrscheinlich ein zusätzlicher Wert (Integer, Farbbyte) ... und die Elementgröße muss sowohl den Schlüssel als auch den Wert berücksichtigen –

+0

David, änderte es in * untere Grenze *, um es klarer zu machen, der Rest sollte sein * –

7

Kurze Antwort: Nein

Lange Antwort:
-> Das grundlegende Objekt ja. sizeof (<TYPE>), aber dies ist nur für begrenzte Dinge nützlich.
-> Behälter und die darin enthaltenen Mitglieder: NO

Wenn Sie Annahmen über die Strukturen machen diese Objekte zu implementieren, können Sie es schätzen. Aber auch das ist nicht wirklich nützlich (abgesehen von dem ganz speziellen Fall des Vektors).

Die Entwickler der STL haben die Datenstrukturen, die von diesen Containern verwendet werden sollten, bewusst nicht definiert. Es gibt mehrere Gründe dafür, aber einer von ihnen (meiner Meinung nach) besteht darin, die Leute davon abzuhalten, Annahmen über die Interna zu machen und auf diese Weise dumme Dinge zu versuchen, die nicht durch die Schnittstelle gekapselt sind.

Also kommt die Frage auf, warum müssen Sie die Größe wissen?
Müssen Sie wirklich die Größe wissen (unwahrscheinlich aber möglich).

Oder gibt es eine Aufgabe, die Sie versuchen zu erreichen, wo Sie denken, dass Sie die Größe benötigen?

8

Wie können wir den Speicher verwendet finden (in Bytes) durch die Objekte Begriff und termsMap. Haben wir eine Bibliothek?

Sie sollten Ihren eigenen Zuordnertyp verwenden.

typedef std::set<string, 
    your_allocator_1_that_can_count_memory_consumption_t> Terms; 

typedef std::map<string, std::pair<int,Terms>, 
    your_allocator_2_that_can_count_memory_consumption_t> TermMap; 

typedef std::multimap<int, string, greater<int>, 
    your_allocator_3_that_can_count_memory_consumption_t> TermsMap; 

Ich habe noch nicht diese Idee für std :: string überprüft dann, wenn es schwierig ist, einfach zu implementieren Ihre eigene Klasse fixed_string verwenden, die nur char s wickelt [max-String-Länge].

Und wenn Sie in Ihrem Programm müssen es nur aus your_allocator_1_that_can_counts_memory_consumption_t, your_allocator_2_that_can_counts_memory_consumption_t, your_allocator_3_that_can_counts_memory_consumption_t bekommen Speicherverbrauch zu erfahren.

Edited

Für UncleBens ich meinen Punkt klären wollen.

Soweit ich die Frage der ARV verstehe, ist es notwendig zu wissen, wie viel Speicher für set :: set und std :: map zugewiesen ist, einschließlich aller Speicher für Elemente des Satzes und der Karte zugeordnet. Es ist also nicht nur die Größe (Begriffe).

Also habe ich nur einen sehr einfachen Zuweiser vorgeschlagen. Ohne in zu vielen Details könnte es so aussehen:

template <class T> 
class your_allocator_1_that_can_counts_memory_consumption_t { 
public: 
    // interfaces that are required by the standart 
private: 
    std::allocator<T> std_allocator_; 
    // here you need to put your variable to count bytes 
    size_t globale_variable_for_allocator_1_to_count_bytes_; 
}; 

Dieses allocator zählt nur Anzahl der zugewiesenen und nicht zugeordneten Bytes und für echte Zuweisung und Freigabe seines Mitglied std_allocator_ verwenden. Ich muss es möglicherweise unter gdb debuggen, um einen Haltepunkt auf malloc() und auf free() zu setzen, um sicherzustellen, dass jede Zuordnung und Freigabe tatsächlich meinen Zuordner durchläuft.

Ich wäre dankbar, wenn Sie mich auf einige Probleme mit dieser Idee hinweisen, da ich es bereits in meinem Programm implementiert habe, das auf Windows, Linux und HP-UX läuft und ich einfach meine Zuordner frage, wie viel Speicher Jeder meiner Container benutzt.

+1

Ich vermute, dass, wenn Ihr Allokator einige sehr betriebssystemspezifische Zuteilungsroutinen verwendet, Sie nicht in der Lage sein werden, die Speicherbelegung selbst dann zu bestimmen.Wenn ich mich nicht irre, wenn Ihr Code etwas als enthält high-level als 'malloc (n);' es könnte immer noch vollständig implementationsdefiniert sein, wieviel Speicher tatsächlich "verbraucht" wurde. – UncleBens

+0

Siehe den bearbeiteten Teil. –

+0

Noch ein Punkt über 'es könnte noch vollständig implementiert werden definiert, wie viel Speicher tatsächlich "verbraucht" wurde. Das ist wahr. Wenn Sie beispielsweise bei HP-UX nach 5 Bytes fragen, werden manchmal tatsächlich 16 Bytes zugewiesen, da sich libc um die Speicherfragmentierung kümmert. Ich bekomme aber auch Informationen von HP-UX/Linux, wie viel Speicher einem Prozess zugewiesen ist. Als Ergebnis weiß ich, dass der reale Speicherverbrauch größer ist. Übrigens hat ARV nicht gesagt, dass er den genauen Speicherverbrauch durch die Container wissen wollte, einschließlich was von einer libc hinzugefügt werden könnte. –

Verwandte Themen