функция-член класса завершается с ошибкой, когда по крайней мере два экземпляра класса объявлены ранее

#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 )?? Из вашего описания вы сказали, что глобальных значений нет, поэтому я бы предположил, что это не так.