#c #inheritance
#c #наследование
Вопрос:
У меня есть два класса, BTLeafNode и BTNonLeafNode, каждый из которых является производным от моего класса BTreeNode. BTreeNode имеет защищенный буфер-элемент данных, который представляет собой массив символов размером 1024 байта. BTreeNode имеет шаблонную функцию inserttemp, которая хранит пары int-T в буфере, где T — это тип, с которым вызывается функция. Каждый класс имеет свою собственную функцию insert, которая вызывает inserttemp. BTNonLeafNode сохраняет пары int-PageId (PageId в основном является int), а BTLeafNode сохраняет пары int-RecordID (идентификатор записи состоит из PageId и int) в буфер. Я еще не тестировал BTNonLeafNode, но по какой-то причине, когда у меня есть только два экземпляра BTLeafNode, и я вызываю функцию insert, она работает нормально, но для любого экземпляра BTLeafNode, который был объявлен после объявления по крайней мере двух экземпляров BTLeafNode, это приводит к сбоям. Часть памяти, которая должна хранить значение int в RecordID, вместо этого сохраняет значение int следующей пары int-RecordID (эти две части данных хранятся рядом друг с другом в буфере).
Я действительно в замешательстве, потому что я не понимаю, почему объявление экземпляра испортит функцию. Нет никаких глобальных переменных. Вам даже не нужно ничего делать с объявленными экземплярами, пока вы их объявляете, это портит функцию.
Комментарии:
1. Было бы полезно опубликовать минимальный код, который воспроизводил бы это поведение. Трудно сказать, не видя, что вы делаете.
2. Я сомневаюсь, что вставка слишком похожа на другие, которые прокомментировали. Похоже, происходит переполнение буфера. Если вы используете MS visual Studio, используйте флаг ‘/GS’ (возможно, также ‘ /GZ’) для проверки переполнения буфера. Это вызовет исключение при переполнении буфера, и вы можете проверить callstack
Ответ №1:
На данный момент нет опубликованного кода, поэтому мы не можем точно видеть, что происходит, но если вы не объявили какой-либо элемент данных в качестве статического элемента данных, и каждый производный экземпляр BTreeNode
имеет свой собственный закрытый буфер, тогда я могу в значительной степени гарантировать, что проблема не имеет ничего общего с наследованием или количеством экземпляров производного объекта, которые вы объявляете, но, скорее всего, проблема с вашим алгоритмом вставки. Это может быть небольшая ошибка, которая проявляется не во всех случаях, отсюда и причина, по которой некоторые вставки срабатывают, но опять же, поскольку у каждого объекта экземпляра есть свой собственный буфер памяти, то единственный способ, которым у объекта экземпляра мог быть поврежден буфер памяти, — это если алгоритм в функции-члене, которая обращается к массиву объекта экземпляра, имеет проблему.
Также вы сказали, что в каждом экземпляре a есть массив символов размером 1024 байта BTreeNode
, но вы сохраняете пары, используя шаблонную функцию … выполняете ли вы какой-либо тип приведения пары к a unsigned char*
и используете memcpy()
для выделения структуры пары в буфере? Если это так, то многое может пойти не так, если вы не будете осторожны с тем, как вы увеличиваете и приводите свои указатели.
Комментарии:
1. Я не выполняю никакого приведения, но я использую memcpy () для сохранения пар в буфер. Но я на 95% уверен, что это должно что-то делать с объявлением более двух экземпляров. Я тестировал это кучу раз. Я могу запустить фрагмент кода, который отлично работает с экземплярами to, а затем ничего не менять, за исключением добавления одного экземпляра перед всеми остальными, и последний экземпляр перестает работать должным образом.
2. Является ли буфер общим (т.Е.
static
)?? Из вашего описания вы сказали, что глобальных значений нет, поэтому я бы предположил, что это не так.