Kann ich die Größe eines mit "new type [n]" erstellten Arrays in C ++ angeben?

8

Mit C ++ 11 möchte ich ein Array von booleschen Werten erstellen und es sofort löschen

%Vor%

n ist variabel.

Löst das bereits den vom Array belegten Speicher? Wenn nicht, gibt es einen besseren Ansatz, um das Array zu löschen, als eine Schleife über alle Elemente zu verwenden, indem jedes einzeln auf false gesetzt wird?

Ich habe es in Erwägung gezogen, std: memset () zu verwenden, aber dazu muss ich die Größe des Arrays kennen. Jetzt könnten Anfänger sagen: Einfach, die Größe ist n * sizeof (bool). Aber ich kaufe das nicht. Der Compiler könnte entscheiden, sie anders zu packen, sogar sie als Bits zu packen, nicht wahr?

Gibt es also eine Möglichkeit, die Größe des Arrays sauberer zu bestimmen? Ich stelle mir vor, es könnte eine Funktion std: arraysize () geben, die einfach den Speicherplatz des zugewiesenen Arrays im Speicher zurückgibt. Schließlich muss diese Information zur Laufzeit irgendwie beibehalten werden, oder ein Löschaufruf würde nicht wissen, wie viel freigegeben werden soll, oder?

    
Thomas Tempelmann 14.08.2013, 10:26
quelle

7 Antworten

10

Die Antwort auf die spezifische Frage lautet nein, Sie können die Länge des Arrays, auf das von mymap verwiesen wird, nicht bestimmen. Die Sprache bietet dafür einfach keinen Mechanismus.

Wenn Sie jedoch nur sicherstellen möchten, dass alle Elemente des Arrays auf false gesetzt sind, müssen Sie lediglich initialisieren:

%Vor%

Leider funktioniert dies nur für Null-ähnliche Werte für integrierte Typen. Es gäbe keine gleichwertige Möglichkeit, alle Werte auf true zu setzen.

    
juanchopanza 14.08.2013, 10:45
quelle
6

Sie können das nicht auf eine normale Art und Weise tun. Verschiedene Compiler unterstützen jedoch verschiedene Hacks, zum Beispiel:

%Vor%

Aber das sind echte Hacks, also Vorsicht.

Übrigens kann std::vector Ihnen helfen, Ihr Problem innerhalb des Standards zu lösen.

    
Sergey K. 14.08.2013 10:49
quelle
4

Nein, das geht nicht, weil es kein Array ist. mymap ist nur ein normaler Zeiger auf einige Heap-Speicher, und wenn Sie die Größe wissen müssen, müssen Sie entweder selbst nachschauen oder einen Standardcontainer wie std::vector verwenden.

Oh, und wenn Sie eine allgemeinere Variante von memset möchten, lesen Sie std::fill .

    
Some programmer dude 14.08.2013 10:28
quelle
4

Nein, der Compiler kann nicht entscheiden, sie zu packen, außer dass die Größe der Region n * sizeof(bool) ist. Anderenfalls würde die Fähigkeit, einzelne Array-Member als mymap[x] zu adressieren, nicht mehr funktionieren (was gleich ist) als *(mymap + x) ).

In diesem Fall ist der Vorschlag von Anfängern der richtige.

    
user4815162342 14.08.2013 10:30
quelle
2

Sie können dies versuchen:

%Vor%

Dies setzt jedoch auf false und Sie können nicht so auf true setzen.

    
ST3 14.08.2013 11:33
quelle
2

Nehmen wir an, dass der Compiler beschließt, anders zu packen.

Annahme 1: Der Compiler packt einige Bits zu einem Byte zusammen. Wenn Sie die Adresse eines einzelnen Elements im Array verwenden, hat es den Typ bool. Da der Compiler (im Allgemeinen) nicht abziehen kann, was Sie mit dieser Adresse tun werden (z. B. Übergabe an eine Funktion, die ihn an eine Lib weiterleitet, ...), kann Bit-Packing innerhalb eines Bytes nicht wirklich passieren. Andernfalls muss der Compiler das entsprechende Bit aus seiner gepackten Region maskieren und es als echten Booler verschieben.

Annahme 2: Der Compiler verwendet mehr als sizeof (bool) für einen bool-Wert. Sehr unwahrscheinlich - denn dann wäre die Größe von (bool) einfach größer. Zeigermanipulationen sind weiterhin möglich und bei Bit-Arrays muss noch eine andere magische Logik implementiert werden.

Annahme 3: Der Compiler verwendet verschiedene Größen für die verschiedenen Felder des Arrays - noch unwahrscheinlicher. Die erforderlichen Verwaltungsinformationen sind einfach zu groß.

Aus diesen drei Gedanken würde ich sagen, dass die einfache Lösung die beste ist. Nur um sicher zu sein, jetzt und die ganze Zukunft Ihres Programms, schreiben Sie einen kleinen Unit-Test, der genau das testet (zB die Adresse des ersten Wertes holen, ihn auf einen Zeiger eines Typs werfen, der die gleiche Größe wie bool hat, Berechne die Adresse von Element n, wandle diese Adresse zurück in einen Zeiger von bool, schreibe dort etwas und vergleiche mit dem Array-Zugriff). Dann erhalten Sie eine Benachrichtigung, wenn sich etwas ändert - aber ich bezweifle es.

Sidenote - natürlich kann der Compiler immer mehr Speicher als nötig reservieren. Aber trotzdem hat das Array diese Größe (es ist nur in einem größeren Speicherbereich platziert).

    
Tobias Langner 14.08.2013 12:40
quelle
2

In blankem C ++ ist das nicht möglich. Sie werden jedoch ermutigt (und sollten es wirklich tun), eine Klasse zu verwenden, um den Speicher trotzdem zu verwalten.

In C ++ 98 können Sie entweder ein boost::scoped_array oder ein std::vector verwenden (obwohl für bool Sie vielleicht ein std::vector<char> bevorzugen).

In C ++ 11 sollten Sie in Erwägung ziehen, boost::scoped_array durch std::unique_ptr<bool[]> zu ersetzen.

Das Problem ist bis dahin, abgesehen von std::vector , keiner von ihnen kennt die Größe des Arrays, das sie enthalten; Sie behandeln nur Speicher.

In C ++ 14 erscheint ein neuer Kandidat: std::dynarray . Es ist eine abgespeckte Version von std::vector , deren Größe nicht dynamisch geändert werden kann. Kurz gesagt, genau das, was Sie wollen: nur das Array und seine Länge, kein Overhead.

Wenn Ihr favorisierter Compiler / toolchain dynarray noch nicht unterstützt, können Sie es einfach selbst implementieren:

%Vor%     
Matthieu M. 14.08.2013 13:06
quelle

Tags und Links