Я пытаюсь иметь три уровня косвенности указателя с дополнительным указателем, указывающим на второй уровень косвенности. Это для класса, и у меня есть некоторые реальные проблемы. Это то, что я делаю.
int ***s = new int **[row];
*s = new int *[row];
**s = new int[row];
Теперь, если бы я мог использовать только int, а не массивы,
***s = 1;
Чтобы сохранить его в желтом квадрате на моей картинке, но я не знаю, как получить доступ к элементам массива, я попробовал несколько вещей, и он либо вылетает, либо не компилируется. Любая помощь, даже указав мне в правильном направлении, была бы очень полезна. Спасибо.
Вы создали что-то вроде этого (предположим, row
2 и тип T
):
T *** + ----- + | | + - / - + / / T ** + - / - + ----- + | | | + ----- + - + - + - / | - / T * | + - / - + ----- + + - + --- + ----- + | | | | | | + ----- + ----- + + - + - + ----- + ---- / - / | \ --- ----- / - / T | \ - + - / - + ----- + + - / - + ----- + + - + - + ----- + + - \ - + ---- - + | | | | X | | | | | | | | + ----- + ----- + + ----- + ----- + + ----- + ----- + + ----- + ---- - +
Каждый узел будет указывать на первый узел следующего уровня. Разыменование каждого уровня даст следующий уровень, но вы также должны позаботиться об индексе элемента в массиве, который хотите достичь. Это, я вижу, не сделано в вашем коде. Для скаляров вы разыменовываете используя *
в то время как для массивов синтаксис индекса массива слишком разыменовывается, кроме выбора правильного элемента. *
на массивах просто даст вам первый элемент всегда.
Чтобы получить доступ X
на рисунке выше вы бы сделали
T** v = u[0];
T* w = v[1];
T x = w[0];
// shorthand for above
x = u[0][1][0];
Чтобы просто иметь массив на последнем уровне, вы должны делать это
int*** p = new int**;
*p = new int*;
**p = new int[row];
Это просто даст вам █ → █ → █ → █ █ █…, где p
Само по себе (первое поле) является автоматической переменной (обычно хранится в пространстве стека), а остальное приходит из свободного хранилища (обычно находящегося в куче).
Скажем row = 3
для этого примера.
int ***s;
// s=[?]
// s is an uninitialized variable.
s = new int **[row];
// s[*] -> [?]
// [?]
// [?]
// s points to the first element of an array of size 3.
// The elements are uninitialized.
*s = new int *[row];
// s=[*] -> [*] -> [?]
// [?] [?]
// [?] [?]
// We've initialized s[0]. It points to another array of size 3.
// All elements of that array are also uninitialized, along with s[1] and s[2].
**s = new int[row];
// s=[*] -> [*] -> [*] -> [?]
// [?] [?] [?]
// [?] [?] [?]
// More of the same. s[0][0] is initialized.
// This last array contains uninitialized ints, not pointers.
***s = 1;
// s=[*] -> [*] -> [*] -> [1]
// [?] [?] [?]
// [?] [?] [?]
// We traverse three levels of pointers (->) and store 1 in the cell.
Все это должно скомпилироваться и работать нормально (если у вас нет доступа ни к одному из неинициализированных элементов).
s + 1
указывает на второй элемент первого массива.
// s=[*] -> [*] -> [*] -> [1]
// s + 1 -> [?] [?] [?]
// [?] [?] [?]
*(s + 1)
относится к клетке [?]
указал на s + 1
на диаграмме выше. Эта ячейка неинициализирована.
**(s + 1)
пытается разыменовать указатель мусора, который является недопустимым (и часто вылетает).