Почему указатель приведен от двойного *** к двойному ** к нарушению прав записи?
Я должен интегрировать код из tetgen (генератор сетки), который, очевидно, используется довольно часто. Однако я должен использовать старую версию (1.4.3 вместо 1.5), и это дает мне "нарушение прав доступа при записи". Соответствующая функция здесь:
void tetgenmesh::dummyinit(int tetwords, int shwords)
{
unsigned long alignptr;
// Set up 'dummytet', the 'tetrahedron' that occupies "outer space".
dummytetbase = (tetrahedron *) new char[tetwords * sizeof(tetrahedron)
+ tetrahedrons->alignbytes];
// Align 'dummytet' on a 'tetrahedrons->alignbytes'-byte boundary.
alignptr = (unsigned long) dummytetbase;
dummytet = (tetrahedron *)
(alignptr + (unsigned long) tetrahedrons->alignbytes
- (alignptr % (unsigned long) tetrahedrons->alignbytes));
// Initialize the four adjoining tetrahedra to be "outer space". These
// will eventually be changed by various bonding operations, but their
// values don't really matter, as long as they can legally be
// dereferenced.
dummytet[0] = (tetrahedron) dummytet;
dummytet[1] = (tetrahedron) dummytet;
dummytet[2] = (tetrahedron) dummytet;
dummytet[3] = (tetrahedron) dummytet;
...
...
...
}
'dummytetbase' и 'dummytet' - это двойные *** указатели, тетраэдр - двойной ** указатель.
Пример значения:
"tetwords" это: 12.
'(беззнаковые длинные) тетраэдры-> выровненные байты': 8.
'tetwords * sizeof (тетраэдр) + тетраэдры->alignbytes' составляет: 104.
'(alignptr% (unsigned long) tetrahedrons-> alignbytes)' равно: 0.
Код компилируется нормально, но когда приведение указателя от dummytet к dummytet[0] должно быть выполнено, я получаю это "нарушение прав записи".
Итак, dummytet получает адрес dummytetbase + 8. А также dummytet[x] получает все тот же адрес, но это приводит к нарушению записи.
Есть идеи, почему это происходит? Спасибо!
1 ответ
Просто: double***
а также double**
совершенно разные типы. double***
указывает на double**
в то время как double**
указывает на double*
, Применить эту логику рекурсивно.
Теперь, поскольку оба являются указателями, компилятор будет использовать 32 или 64 бита для обоих. Вы можете сказать компилятору заткнуться, отбросить разницу и игнорировать эту проблему во время компиляции. Это означает, что ваша проблема во время компиляции теперь имеет симптомы во время выполнения.
Сделайте шаг назад: если у вас есть T* ptr
и нужна T
ценность, ты не пишешь (T) ptr
, Ты пишешь *ptr
, или же ptr[5]
, или что-то типа того. Это все еще имеет место, когда T==double**
,