2012-03-18 25 views
8

I dati in std::array<std::array<T,N>, M> sono contigui? Ad esempio:I dati in std :: array nidificati sono garantiti come contigui?

#include <array> 
#include <cassert> 

int main() 
{ 
    enum {M=4, N=7}; 
    typedef std::array<char,N> Row; 
    typedef std::array<Row, M> Matrix; 
    Matrix a; 
    a[1][0] = 42; 
    const char* data = a[0].data(); 

    /* 8th element of 1D data array should be the same as 
     1st element of second row. */ 
    assert(data[7] == 42); 
} 

L'affermazione è garantita? O, per dirla in altro modo, posso contare sul fatto che non ci sia padding alla fine di un ?

EDIT: Giusto per essere chiari, per questo esempio, voglio che i dati della intera matrice di essere contigui.

+0

Anche se lo spazio di archiviazione è contiguo, credo che si verifichino violazioni delle regole di aliasing. Vedi questa domanda Ho chiesto molte lune fa (circa C, ammesso): http://stackoverflow.com/questions/6290956/one-dimensional-access-to-a-multidimensional-array-well-defined-c. –

+0

possibile duplicato di [La memoria in std :: array è contigua?] (Http://stackoverflow.com/questions/6632915/is-the-memory-in-stdarray-contiguous) per ricorsione –

+2

@LightnessRacesinOrbit: No, I non pensare che sia un duplicato Mentre i dati in un singolo 'std :: array' sono contigui, ciò non implica che l'intero insieme di dati nello' std :: array's annidato sia contiguo. O almeno non è ovvio per un avvocato non linguista come me. –

risposta

10

No, la contiguità non è garantita in questo caso.

std::array è garantito come aggregato ed è specificato in modo che l'array sottostante utilizzato per la memorizzazione deve essere il primo membro di dati del tipo.

Tuttavia, non è richiesto che sizeof(array<T, N>) == sizeof(T) * N, né vi sia alcun requisito che non ci siano byte di riempimento senza nome alla fine dell'oggetto o che std::array non disponga di membri di dati diversi dalla memoria dell'array sottostante. (Anche se un'implementazione che includeva membri di dati aggiuntivi sarebbe, nel migliore dei casi, insolita.)

5

Sono molto probabilmente contigui. Se non lo sono, il compilatore ti sta attivamente combattendo. Non c'è alcuna garanzia che non inserirà il padding, ma non c'è una ragione per questo.

L'affermazione è garantita?

data[7] è un accesso fuori limite (comportamento non definito). L'oggetto dell'array interno ha solo sette elementi, quindi l'indice 7 non è valido.

+0

Hmm, la tua risposta sembra un po 'contraddittoria (o sono solo troppo densa). Se i dati sono contigui, 'data [7]' non punta al primo elemento della seconda riga? –

+0

@Emile il difetto nel pensare "L'ottavo elemento dell'array dati 1D dovrebbe essere uguale al primo elemento della seconda riga." sta ignorando che nessuna matrice in quel codice ha un ottavo elemento. Non c'è alcuna garanzia su cosa 'data [7]' farà a causa di ciò.In pratica, sì, ho il sospetto che indicherà il primo elemento della seconda riga, ma come sempre è con UB, * non puoi fare affidamento sicuro su di esso *. –

+0

Ok, allora prendo "* sono molto probabilmente contigui *" per indicare che i dati in ** ogni array interno ** sono contigui. È questo che intendevi? –

Problemi correlati