Когда в NDK будет вызываться деструктор C++ для глобальной переменной?

Недавно я столкнулся со странной проблемой при компиляции консольной программы Android с помощью NDK.

Класс объявляется так:

class ClassP
{
public:
    ~ClassP()
    int number;
}
ClassP::~ClassP()
{
    printf("number=%d", number);
}

Основная функция такая:

// global variable
ClassP p_instance;

int main()
{
    printf("test");
}

Когда программа будет выполнена, она выведет

test
Segmentation fault

После некоторой базовой отладки я обнаружил, что при вызове деструктора ClassP адрес его переменной-члена равен 0. Я думаю, это потому, что p_instance каким-то образом освобождается до вызова деструктора. Но поведение не то, что я ожидал. Разве деструктор глобальных переменных не вызывается, когда процесс завершается и система пытается освободить все объекты?


person ccyang    schedule 21.10.2011    source источник
comment
Это C++, используйте cout вместо printf, добавьте return 0; в main, инициализируйте number в default constructor и повторите попытку. Я вообще не знаком с NDK и андроидом, но это все же C++   -  person Kiril Kirov    schedule 21.10.2011
comment
@KirilKirov В printf нет ничего плохого. Проблема с cout заключается в том, что он полагается на объекты, которые могут быть деконструированы раньше, чем ваш объект.   -  person Pubby    schedule 21.10.2011
comment
Вы пытались использовать атрибуты функций constructor и destructor GCC? Если вы не можете заставить свой класс работать, то, возможно, они смогут.   -  person Pubby    schedule 21.10.2011


Ответы (2)


Глобальные переменные уничтожаются, когда их процесс закрывается или, когда их модуль/dll выгружается.

Я предполагаю, что ваша проблема связана с тем, как вы регистрируете свой модуль в NDK, похоже, что ваш код либо НЕ объявляется как глобальная переменная, как вы предполагаете (т.е. он фактически вызывается в области видимости), либо модуль загружается, выгружается, затем как-то вызывается ваша функция.

Взгляните на некоторые примеры NDK в SDK и посмотрите, делаете ли вы что-то очень простое неправильно; потому что ваш код в его нынешнем виде в порядке.

person Mahmoud Al-Qudsi    schedule 21.10.2011
comment
Спасибо за ваш ответ. Я проверю несколько образцов NDK. Кстати, код правильно работает на ПК с Linux (скомпилирован g++). - person ccyang; 24.10.2011

class ClassP
{
    public:
        ~ClassP();
        int number;
};
ClassP::~ClassP()
{
    printf("number=%d", number);
}

// global variable
ClassP p_instance;

int main()
{
    printf("test");
}

Добавьте недостающие точки с запятой

После определения класса и после деструктора класса и деструктор работает нормально

Выход Ps = тестовый номер = 0

person Aiden Strydom    schedule 21.10.2011
comment
@Kiril Kirov - вы не можете инициализировать переменную в конструкторе по умолчанию, поэтому это конструктор по умолчанию, если вы создаете конструктор, он затем называется конструктором без аргументов. если вы не создаете конструктор, тогда C++ создает con по умолчанию.. для вас Просто FYI - person Aiden Strydom; 21.10.2011