Я столкнулся со странной проблемой, которую мне удалось отследить, но я до сих пор не вижу причины. Может быть, кто-то здесь может пролить свет?
Я использую процессор PowerPC поверх VxWorks 5.5, разрабатываемого на C ++ с помощью цепочки инструментов PPCgnu604.
У меня есть такой класс:
class MyClass
{
public:
void run( void );
private:
CommandMesssageClass command;
StatusMessageClass status;
};
Когда мое приложение запускается, оно динамически выделяет экземпляр MyClass и порождает поток, указывающий на его функцию «run». По сути, он просто сидит там, опрашивая команды, и после получения выдаст статус обратно.
Обратите внимание, что это урезанная версия класса. Есть несколько других методов и переменных, оставленных для краткости.
Проблема, которую я вижу, состоит в том, что, когда и команда, и сообщения о состоянии определены как закрытые члены класса, я получу изменение в доступных байтах в памяти, несмотря на то, что не должно быть динамического выделения памяти. Это важно, потому что это происходит в процессе, который должен быть детерминированным и безопасным для скорости.
Если я переместлю одно или оба объявления сообщений в функцию run, она будет работать нормально без дополнительного выделения!
Мне, должно быть, не хватает чего-то фундаментального в моем понимании объявлений C ++ и распределения памяти. Насколько я понимаю, экземпляр класса, который я динамически создаю, будет полностью размещен в куче (включая все переменные-члены) при его создании. Различие, которое я вижу здесь, состоит в том, что перемещение объявлений сообщений в функцию run помещает их в стек. Куча в этом случае более чем достаточно велика, чтобы соответствовать всему размеру класса. Почему кажется, что он не выделяет достаточно памяти, пока не будут использованы определенные части?
Классы сообщений не имеют собственного динамического распределения. (И если бы они это сделали, я ожидал бы, что перемещение объявления не изменит поведение в этом случае, и я все равно увижу изменение размера кучи.)
Для отслеживания распределения памяти я использую следующий вызов memxib (или memPartLib) из VxWorks:
memPartInfoGet( memSysPartId, &partitionStatus );
...
bytesFree = partitionStatus.numBytesFree;
Edit:
Для пояснения, объект MyClass создается и инициализируется в процедуре инициализации, а затем код входит в безопасную для скорости обработку. В течение этого времени после получения командного сообщения по последовательной линии (первое взаимодействие с объектами сообщения «Команда» или «Состояние») выделяется дополнительная память (или, точнее, уменьшается количество свободных байтов). Это плохо, потому что динамическое распределение памяти не является детерминированным.
Мне удалось избавиться от проблемы, переместив переменные класса, как я описал.