Запретить компиляцию malloc / free для встроенных проектов - PullRequest
4 голосов
/ 05 августа 2011

Справочная информация: Мы используем Keil для компиляции нашего проекта NXP LPC2458.Есть множество задач, которые выполняются в RealView RTOS Keil.Создано пространство стека, которое выделяется для каждой задачи.Нет HEAP, созданного по умолчанию, и я хочу избежать этого, так как мы не можем позволить себе накладные расходы на пространство кода и затраты на «сбор мусора»

Цель: использовать C ++ во встроенном коде без использованиякуча.Keil предоставляет #pragma (__use_no_heap), который предотвращает связывание вызовов malloc () и free ().

Решение: я попытался создать Singleton с частным статическим указателем.Я надеялся, что new () не будет вызываться, так как я объявил dlmData как статический в getDLMData ().По какой-то причине компоновщик по-прежнему заявляет, что malloc () и free () вызываются.У меня есть мысли о частном операторе new () и частном операторе delete (), а затем о объявлении dlmData как статического в перегруженной функции.Это не работает по какой-то причине.ЧТО Я ДЕЛАЮ НЕПРАВИЛЬНО?

    //class declaration
    class DataLogMaintenanceData
    {
    public:
      static DataLogMaintenanceData* getDLMData();
      ~DataLogMaintenanceData()
      { instanceFlag = FALSE; }
    protected:
      DataLogMaintenaceData(); //constructor declared protected to avoid poly
    private:
      static Boolean instanceFlag;
      static DataLogMaintenceData *DLMData;
    }

    //set these to NULL when the code is first started
    Boolean DataLogMaintenanceData::instanceFlag = FALSE;
    DataLogMaintenanceData *DataLogMaintenaceData::DLMData = NULL;    

    //class functions
    DataLogMaintenanceData *DataLogMaintenanceData::getDLMData()
    {
        if (FALSE == instanceFlag)
        {
            static DataLogMaintenanceData dlmData;
            DLMData = &dlmData;
            instanceFlag = TRUE;
            return DLMData;
        }
        else
        {
            return DLMData;
        }
    }

    void InitDataLog ( void )
    {
        DataLogMaintenanceData *dlmData;
        dlmData = DataLogMaintenanceData::getDLMData();
        // to avoid dlmData warning
        dlmData = dlmData;
    }

    //ACTUAL TASK
    __task DataLog()
    {
      .. .. .. code to initialize stuff

      InitDataLog();

      .. .. ..more stuff
    }

По какой-то причине единственный способ, которым я могу заставить это скомпилировать, состоит в том, чтобы создать пространство кучи и затем позволить вызовам malloc () и free () компилироватьсяв проект.Как и ожидалось, «статический» определенный объект-союзник, dlmData, находится в пространстве ОЗУ, выделенном для модуля dataLog.o (т.е. он не находится в HEAP).

Я не могу понять,и я проверил Google, что мне не хватает?Возможно ли в C ++ обойти malloc () и free () при компиляции чистых объектов?Я знаю, что могу заменить реализацию malloc () и free () в ОСРВ, чтобы ничего не делать, но я хочу избежать компиляции в коде, который я не буду использовать.

Ответы [ 3 ]

2 голосов
/ 05 августа 2011

Возможно, некоторый код, который мы не видим, вызывает функцию, которая вызывает malloc за кулисами.

С http://www.keil.com/support/man/docs/armlib/armlib_CJAIJCJI.htm вы можете использовать --verbose --list=out.txt в строке ссылки, чтобы получитьподробности о malloc звонящем.

1 голос
/ 08 августа 2011

В комплект Keil входит набор файлов PDF ... один из документов (идентификатор документа DUI0475A) называется «Использование библиотек ARM C и C ++ и поддержка с плавающей запятой». В нем обсуждается использование кучи (и предотвращение ее использования) в нескольких местах.

В частности, ознакомьтесь с разделом 2.64 «Как избежать использования библиотек кучи и библиотек, использующих ARM», там много полезной информации. Интересный текст в этом разделе:

Вы можете ссылаться на символы __use_no_heap или __use_no_heap_region в ваш код, чтобы гарантировать, что никакие функции кучи не связаны в библиотека ARM.

__use_no_heap защищает от использования malloc (), realloc (), free (), и любая функция, которая использует эти функции. Например, calloc () и другие функции stdio.

__use_no_heap_region имеет те же свойства, что и __ use_no_heap , но в Кроме того, защищает от других вещей, которые используют область памяти кучи. Например, если вы объявляете main () как функцию, принимающую аргументы, регион кучи используется для сбора argc и argv.

Поскольку ваш вопрос касается того, как предотвратить вызов / использование malloc(), это может поставить вас на правильный путь.

0 голосов
/ 06 августа 2011

Из кода, который вы выложили, я не вижу ничего, что бы выделило память в куче. Есть ли какие-то неявные преобразования где-нибудь? Что если вы вообще скомпилируете без этого класса?

Что вы могли бы сделать:

1) Запустить под отладчиком (при условии, что вы можете создать работающий образ, возможно, на эмуляторе), установить точку останова в malloc и проверить стек

2) Предоставьте свой собственный malloc и бесплатно, чтобы компоновщик был доволен, затем повторите шаг 1.

Вы можете обнаружить, что вам нужно установить связь с другой версией запуска C. В худшем случае, если количество обращений к malloc / free ограничено, вы можете развернуть свою собственную версию, которая даст вызывающим абонентам некоторую предварительно выделенную память - но, надеюсь, это не будет необходимо.

...