C ++ не может написать 1-е члену структуры - PullRequest
1 голос
/ 10 февраля 2012

У меня небольшая проблема с записью 1 для члена структуры.

У меня есть структура, которая представляет Voxel, который может иметь 8 дочерних элементов (идентификаторы 0-7).Чтобы указать, у каких детей есть Voxel, я использую 8-разрядное целое число без знака.Если у Voxel есть определенный дочерний элемент, то бит в позиции дочернего элемента, равный идентификатору дочернего элемента, устанавливается равным 1.

Например, если дочерний элемент Voxels сохранил значение: 10000101 Тогда Voxelбудет иметь детей 0, 2 и 7 (справа налево).

Код структуры Voxel выглядит следующим образом:

typedef struct Voxel {
       uint8_t children; //list of children
       Voxel* firstChildPointer;
};

Первый дочерний указатель указывает на начало спискавокселей, которые являются вокселями дочерних элементов.

Проблема возникает при желании добавить дочернего элемента.Мне нужно изменить член детей, чтобы отразить добавленного ребенка.Однако при этом я получаю исключение времени выполнения, в котором говорится «Место записи нарушения доступа», за которым следует адрес памяти.

Код, который я использую для изменения дочерних элементов, приведен ниже:

void addVoxel(Voxel* parent, char childID) {
       parent->children |= (1 << childID); }

Когдавсе Voxels сначала загружаются в память, дочерние элементы Voxel устанавливаются без ошибок.Но после этого я не могу написать 1 для участника.0 пишут отлично.Я пытался использовать много методов, чтобы написать вещи, даже простое старое присвоение номера.Но если число имеет больше 1, то оно не будет работать.

Так получилось, что указатель на родителя в этом случае сохраняется как глобальная переменная, и каждый воксель также хранит указатель на своих потомков,может ли это быть проблемой?Если так, то передача родителя в качестве справки поможет?Я знаю, как сделать это в C #, но не в C ++.

Любая помощь будет отличной.

S.

РЕДАКТИРОВАТЬ:

Добавить воксельметод вызывается с использованием этой строки:

addVoxel(octree, 4);

octree - это указатель вокселя, как определено:

Voxel* octree = octreeLoader.loadVoxelData();

Метод загрузки данных вокселя загружает информацию о октрее из файла.Мы знаем, что этот раздел и указатель возврата работают, поскольку мы используем их точную копию для трассировки лучей.Однако, вкратце, указатель создается с использованием этой строки:

Voxel* octree;

, а затем назначается память с использованием этой строки:

octree = (Voxel *) calloc(1, sizeof(Voxel));

Затем дочерние элементы назначаются с использованием этой строки:

octree[0].children = children;

Каждый следующий потом создается таким же образом и получает память.Я проверил, что дочерний элемент инициализирован правильно, а childID верен.

Ответы [ 3 ]

1 голос
/ 10 февраля 2012

Каким-то образом ваш родительский указатель недействителен. В противном случае изменение номера не может привести к нарушению доступа. Я полагаю, вы используете эти индексы для обхода дерева? Вы должны попробовать такой инструмент, как valgrind. Это может облегчить отладку.

0 голосов
/ 10 февраля 2012

Ваша проблема пахнет какой-то коррупцией: особенно то, что вы можете писать нули, но не единицы - это звучит так, как будто вы пишете не туда, куда, как вы думаете, пишете (какие-то дополнения или данные, которые для чего угоднопричина должна обнуляться).Либо это, либо вы просто не должны изменять эти данные таким образом после инициализации вокселей.

У вас включены все возможные проверки отладки и защита?Среда выполнения C может вам очень помочь, если это какая-то ошибка

Если вы уже работаете со всеми включенными параметрами отладки, при отладке учитывайте следующие значения:

* 0xABABABAB : Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory
* 0xABADCAFE : A startup to this value to initialize all free memory to catch errant pointers
* 0xBAADF00D : Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory
* 0xBADCAB1E : Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger
* 0xBEEFCACE : Used by Microsoft .NET as a magic number in resource files
* 0xCCCCCCCC : Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory
* 0xCDCDCDCD : Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory
* 0xDEADDEAD : A Microsoft Windows STOP Error code used when the user manually initiates the crash.
* 0xFDFDFDFD : Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory
* 0xFEEEFEEE : Used by Microsoft's HeapFree() to mark freed heap memory

Если вы видите, что какое-либо из этих значений используется вместо действительных данных, что-то пошло не так

РЕДАКТИРОВАТЬ: Кроме того, кое-что трудно выяснить из вашего вопроса: это только воксельные данные или есть другие вспомогательные данные - например,индексы или координаты цвета / текстуры какого-то рода?Если запись 1, включающая дочерние элементы, дает сбой, действительно ли их рисование приводит к тому, что некоторые другие данные используются / требуются?(что по какой-то причине не доступно).Вы получаете тот же сбой, если сначала отключите дочерний элемент, записывающий ноль, а затем re - включите его?Или вы получаете сбои только при включении детей, которых раньше не было вообще?

0 голосов
/ 10 февраля 2012

Вы пытались использовать unsigned char вместо char? Это может не быть проблемой, но это может компенсировать знак, делая что-то напуганное. Вы утверждаете, что & = работает, однако, присваивание AND не будет присваивать значения 1, оно будет заменено только на 0 ..., поэтому оно может не завершиться сбоем. Использование | = это установка в единицу. Вы заявляете, что 0 отлично работает, если это так, & = будет работать.

...