2016-05-03 7 views
0

Ich habe ein Array als dt [100] verwendet; dann habe ich die Werte wie memset (dt, 63, sizeof (dt)) initialisieren; dann habe ich den Wert in diesem Array wie 4557430888798830399 zugeordnet.Kann ich die Erklärung haben?Initialisieren von Werten durch die Speicherplätze

#include <bits/stdc++.h> 
#define ll long long int 
using namespace std; 
ll dt[100]; 
int main() 
{ 

memset(dt,63,sizeof(dt)); 
cout<<dt[0]<<endl; 

} 
+2

Die Array-Elemente sind vom Typ 'long long',' memset() 'füllt den Speicher auf Zeichenebene. –

+1

Verwenden Sie 'for (size_t i = 0; i

Antwort

9

gut, Antworten hier sind fast richtig.
die flexibelste, richtige Lösung ist std::fill mit std::begin + std::end

std::fill(std::begin(dt),std::end(dt),63); 
  1. zu verwenden, sollten Sie std::fill statt memset verwenden, da std::fill bewusst von Objekten und wird die richtige Zuordnung Betrieb nennen. memset weiß nur, was ein Byte ist (C vs C++).
  2. memset füllt Bytes, füllt std::fill jede Variable mit jeder Größe
  3. std::fill wird memset oder memmove sowieso anrufen, wenn die variable Größe eine Byte-Größe entspricht (ja, die Standard-Bibliothek ist nicht so dumm, wie wir vielleicht denken, es ist ..)
  4. std::begin + std::end die Größe eines C-Array "wissen", so dass keine fehlerhaften Sachen wie arr , arr + 100 die den Moment bricht die Feldgrße
  5. std::begin + std::end Arbeit mit C-Arrays und jedem C++ Behälter, derliefert geändert wirdund end() Methoden (vector , deque , list usw.). also, ohne irgendeine Bemühung zu setzen, ist der Code allgemein (der sizeof Trick funktioniert nicht für std::vector, zum Beispiel).

wie warum tut die long long so seltsame Wert hat, liegt daran, dass memset jedes Byte füllt und nicht jeder long long.
so, vorausgesetzt, jeder long long 8 Bytes, Speicher weise, die long long nachdem der memset wie

sieht
byte 
    | 
    V 
[63][63][63][63][63][63][63][63] 
^        ^
|  long long    | 

und in binär:

0011111100111111001111110011111100111111001111110011111100111111 
//63 == 00111111, 8 bytes of each 

welche ist:

4557430888798830399 

(Ich habe mich bewusst nicht mit Endlichkeitsdetails beschäftigt, um das Thema nicht zu sehr zu verkomplizieren.

1

Wie in einem Kommentar von @ Michael Burr, Funktion erwähnt memset den Wert jedes char in dem gegebenen Speicherblock setzt, während jede Zelle in Array long long ist.

Alternative:

for (size_t i=0; i<sizeof(dt)/sizeof(*dt); i++) 
    dt[i] = 63; 

for (auto& n : dt) 
    n = 63; 
+0

, ich bin nicht auf die Idee gekommen, den Wert jedes Char im gegebenen Block zu setzen ... Ich habe Array von Integer genommen, deshalb Char hat mich verwirrt –

4

Gemäß oben Antworten auf Byte-Ebene Füllung ist der Grund, warum Sie bekommen, was Sie bekommen. Als Alternative zum oben genannten Vorschlägen, könnten Sie verwenden:

std::fill(dt, dt+100, 63); 

Der Vorteil hierbei ist, dass diese eher optimiert werden soll und schneller also als manuell über den Speicherbus Looping (zB es SIMD Vektorbefehle auf x86_64 verwenden könnte Architekturen)

+0

hart Codierung der +100 ist schlechte Praxis, die 100 Abbildung könnte in geändert werden die Deklaration in einigen späteren Refactoring, und es gibt die Möglichkeit, zu vernachlässigen, diese Zeile zu ändern, um das widerzuspiegeln. Außerdem macht es den Füllaufruf abhängig von der Datenstruktur von dt. std :: begin und std :: end abstrahieren die Datenstruktur und ermöglichen größere Flexibilität - und seit C++ 14 funktioniert es auch für Arrays (außer für dynamisch erstellte - die an sich schon eine schlechte Praxis sind - benutze std :: Vektor dafür!) –

2

Wie bereits erwähnt, kopiert die memset 63 Bytes in jedes Byte des Arrays. Deshalb sind Ihre Zahlen nicht das, was Sie erwarten. Sie sollten auch versuchen, memset und memcpy in C++ zu vermeiden und nur verwenden, wenn Sie sicher sind, dass die kopierten Objekte PODs oder Standard-Layout-Typen sind. Das Kopieren allgemeiner C++ - Objekte kann sehr problematisch sein, und das Speichern von Objekten ist ein Rezept für Katastrophen.

Eine Alternative zu std::fill, die völlig in Ordnung ist, ist, keine reinen C-Arrays zu verwenden. Verwenden Sie stattdessen entweder std::vector<long long> oder std::array<long long, N>.

std::vector<long long> v(10, 63); 

Zum Erstellen eine statisch zugewiesenen Array von 10 Elementen mit dem Wert 63

std::array<long, long, 10> a; 
a.fill(63); 

PS::

Um einen Vektor von 10 Elementen mit dem Wert 63 zu erzeugen versuchen, nicht #define für typedefs zu verwenden oder Konstanten oder Inline-Funktionen. C++ hat typsichere Ersetzungen für die meisten C-Konstrukte.

Verwandte Themen