Sto cercando di far puntare un puntatore a un array 2D di puntatori. Qual è la sintassi e come accedo agli elementi?Come allocare un array 2D di puntatori in C++
risposta
Con la lettera della legge, ecco come fare it:
// Create 2D array of pointers:
int*** array2d = new (int**)[rows];
for (int i = 0; i < rows; ++i) {
array2d[i] = new (int*)[cols];
}
// Null out the pointers contained in the array:
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
array2d[i][j] = NULL;
}
}
Fare attenzione a eliminare i puntatori contenuti, gli array di righe e l'array di colonne tutti separatamente e nell'ordine corretto.
Tuttavia, più frequentemente in C++ si dovrebbe creare una classe che gestisca internamente un array di puntatori 1D e sovraccarichi l'operatore di chiamata di funzione per fornire l'indicizzazione 2D. In questo modo hai davvero una serie contigua di puntatori, piuttosto che una serie di matrici di indicatori.
Più simile a un puntatore a un array di puntatori agli array. – Crashworks
@Crahsworks: So. Se cova come un'anatra, è un'anatra. –
Dipende da cosa OP indica con "2d array". Se intende semplicemente qualcosa a cui è possibile accedere con due operatori di pedici 'a [n] [m]', allora sì, questo è digitato anatra come array multidim. Se intende ciò che lo standard specifica come un array 2D, che è una regione contigua di n * m molti elementi, allora un array 1D di puntatori agli array 1D non è la stessa cosa. – Crashworks
double** array = new double*[rowCnt];
for (int row = 0; row < rowCnt; ++row)
array[row] = new double[colCnt];
for (int row = 0; row < rowCnt; ++row)
for (int col = 0; col < colCnt; ++col)
array[row][col] = 0;
questo è solo un puntatore che punta a un array 1D di puntatori. – TheFuzz
Forse la sintassi dell'array [row] [col] lo chiarisce? –
Ma non è ancora contiguo. – Crashworks
È possibile definire un vettore di vettori:
typedef my_type *my_pointer;
typedef vector<vector<my_pointer> > my_pointer2D;
che creare una classe derivata da my_pointer2D, come:
class PointersField: public my_pointer2D
{
PointsField(int n, int m)
{
// Resize vectors....
}
}
PointsField pf(10,10); // Will create a 10x10 matrix of my_pointer
punto! = Puntatore. –
ahh, qualunque sia ... – Elalfer
Inoltre, non si dovrebbe ereditare dai contenitori STL –
int *pointerArray[X][Y];
int **ptrToPointerArray = pointerArray;
Ecco come si crea una matrice multidimensionale (contigua alla memoria) vera.
Ma renditi conto che una volta lanciato un array multidimensionale su un puntatore del genere, perdi la capacità di indicizzarlo automaticamente. Si dovrebbe fare manualmente la parte multidimensionale dell'indicizzazione:
int *pointerArray[8][6]; // declare array of pointers
int **ptrToPointerArray = &pointerArray[0][0]; // make a pointer to the array
int *foo = pointerArray[3][1]; // access one element in the array
int *bar = *(ptrToPointerArray + 3*8 + 1); // manually perform row-major indexing for 2d array
foo == bar; // true
int *baz = ptrToPointerArray[3][1]; // syntax error
C++ è una conversione fortemente tipizzata da int * a int ** non è consentita senza un cast esplicito. –
Vero. Tuttavia, la conversione da int * [] a int **, che è quello che faccio qui, è automatica. – Crashworks
True: Tuttavia questa non è la conversione: int ** ptrToPointerArray = pointerArray; Prova a compilare il codice con un compilatore C++ e vedrai l'errore. –
Vedere il mio codice. Funziona sul mio FC9 sistema x86_64:
#include <stdio.h>
template<typename t>
struct array_2d {
struct array_1d {
t *array;
array_1d(void) { array = 0; }
~array_1d()
{
if (array) {
delete[] array;
array = 0;
}
}
t &operator[](size_t index) { return array[index]; }
} *array;
array_2d(void) { array = 0; }
array_2d(array_2d<t> *a) { array = a->array; a->array = 0; }
void init(size_t a, size_t b)
{
array = new array_1d[a];
for (size_t i = 0; i < a; i++) {
array[i].array = new t[b];
}
}
~array_2d()
{
if (array) {
delete[] array;
array = 0;
}
}
array_1d &operator[](size_t index) { return array[index]; }
};
int main(int argc, char **argv)
{
array_2d<int> arr = new array_2d<int>;
arr.init(16, 8);
arr[8][2] = 18;
printf("%d\n",
arr[8][2]
);
return 0;
}
effo UPD: una risposta a "? Non è che un array di puntatori ad array", aggiungendo l'esempio di array di puntatori, molto semplice:
int main(int argc, char **argv)
{
array_2d<int*> parr = new array_2d<int*>;
int i = 10;
parr.init(16, 8);
parr[10][5] = &i;
printf("%p %d\n",
parr[10][5],
parr[10][5][0]
);
return 0;
}
Ho ancora frainteso la tua domanda?
e si potrebbe anche
typedef array_2d<int*> cell_type;
typedef array_2d<cell_type*> array_type;
int main(int argc, char **argv)
{
array_type parr = new array_type;
parr.init(16, 8);
parr[10][5] = new cell_type;
cell_type *cell = parr[10][5];
cell->init(8, 16);
int i = 10;
(*cell)[2][2] = &i;
printf("%p %d\n",
(*cell)[2][2],
(*cell)[2][2][0]
);
delete cell;
return 0;
}
Funziona anche sul mio sistema FC9 x86_64.
Non è un array di puntatori agli array? – Crashworks
@Crashworks. Anche questo funziona ancora come un array 2D. –
@Effo: questa implementazione ha alcuni bug gravi. Operatore di assegnazione mancante. Possibile doppia eliminazione di puntatori se utilizzati in modo errato. array_1 può essere copiato accidentalmente su una copia locale e al momento della cancellazione verrà eliminata una riga nella matrice. –
:)
ho avuto questi, una volta in un pezzo di codice che ho scritto.
Ero lo zimbello della squadra quando sono usciti i primi bug. Inoltre, utilizziamo la notazione ungherese, che porta a un nome come papChannel
- un puntatore a un array di puntatori ...
Non è bello. È meglio usare typedef per definire una "riga di colonne" o viceversa. Rende anche l'indicizzazione più chiara.
typedef int Cell;
typedef Cell Row[30];
typedef Row Table[20];
Table * pTable = new Table;
for(Row* pRow = *pTable; pRow != *pTable+_countof(*pTable); ++pRow) {
for(Cell* pCell = *pRow; pCell != *pRow + _countof(*pRow); ++pCell) {
... do something with cells.
}
}
Dipende. Può essere semplice come:
int main()
{
int* data1[10][20]; // Fixed size known at compile time
data1[2][3] = new int(4);
}
Se volete i formati dinamici in fase di esecuzione è necessario fare un certo lavoro.
Ma Boost ha coperto:
int main()
{
int x;
int y;
getWidthAndHeight(x,y);
// declare a 2D array of int*
boost::multi_array<int*,2> data1(boost::extents[x][y]);
data[2][3] = new int(6);
}
Se si sta bene con jagged arrays che può crescere in modo dinamico:
int main()
{
std::vector<std::vector<int*> > data1;
data1.push_back(std::vector<int*>(10,NULL));
data1[0][3] = new int(7);
}
Nota: In tutto quanto sopra. Suppongo che l'array non possieda il puntatore. Quindi non ha fatto alcuna gestione sui puntatori che contiene (anche se per brevità sto usando new int() negli esempi). Per fare correttamente la gestione della memoria è necessario fare un po 'più di lavoro.
Si potrebbe provare Boost :: MultiArray.
Per ulteriori dettagli, consultare questo page.
Preferisco utilizzare l'operatore(). Ci sono molte ragioni per questo (FAQ C++ 13.10). Modificare la rappresentazione interna ad un std::vector
se ti piace:
template <class T, int WIDTH, int HIEGHT>
class Array2d
{
public:
const T& operator()(size_t col, size_t row) const
{
// Assert col < WIDTH and row < HIEGHT
return m_data [(row * WIDTH + col)];
}
T& operator()(size_t col, size_t row)
{
// Assert col < WIDTH and row < HIEGHT
return m_data [(row * WIDTH + col)];
}
private:
T m_data[WIDTH * HIEGHT];
};
Si può usare in questo modo:
Array2d< Object*, 10, 10 > myObjectArray;
myObjectArray(5,6) = new Object();
- 1. Come allocare dinamicamente un array di puntatori in C++?
- 2. Heap alloca un array 2D (non un array di puntatori)
- 3. Puntatori a 2D array C, C++
- 4. Come allocare un array 2D utilizzando l'istruzione One malloc
- 5. Accesso a un array 1D come array 2D in C++
- 6. C: scambiatore di puntatori in un array
- 7. incrementare un array di puntatori in C
- 8. Come allocare array di puntatori per stringhe di malloc in C?
- 9. Stampa di un array 2D in C
- 10. In C, sono puntatori di array o utilizzati come puntatori?
- 11. Sintassi per l'allocazione dinamica di un array 2D di puntatori intelligenti
- 12. c puntatori e array
- 13. Come inizializzare un array di array 2D?
- 14. Come faccio a cancellare questo array 2D in C++
- 15. come allocare array di canali in go
- 16. Come restituire un array 2D a una funzione in C?
- 17. Riprodurre un array di puntatori a funzione C in Python
- 18. Conversione array multidimensionali ai puntatori in C++
- 19. funzione puntatori, array e lvalue in C
- 20. Seleziona in un array 2D
- 21. Converti un array di numpy 2D in C++ short **?
- 22. Puntatori in C# per creare array int?
- 23. C++ - array di puntatori su Vector?
- 24. Trasporre un array 2D
- 25. Passando array e matrici a funzioni come puntatori e puntatori ai puntatori in C
- 26. Come si crea un array di puntatori?
- 27. Conversione di un array numpy 2D in un array strutturato
- 28. Come rimuovere un sottoinsieme di array 2d?
- 29. Unione di due array di numpy 2D in un singolo array 2D di 2 tuple
- 30. Array 2D in Kotlin
è la dimensione del sapere al momento della compilazione o creato da dimensioni fisse in fase di esecuzione? Le file e le colonne di Rows hanno dimensioni fisse o cresciute dinamicamente, portando a matrici frastagliate? I puntatori sono di proprietà dell'array o sono semplicemente detenuti? I puntatori sono tutti correlati (cioè lo stesso tipo di base)? –