Почему указатель приведен от двойного *** к двойному ** к нарушению прав записи?

Я должен интегрировать код из 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**,

Другие вопросы по тегам