C++全局变量的析构函数在NDK中何时被调用?

3

最近,我在使用 NDK 编译 Android 控制台程序时遇到了一个奇怪的问题。

该类声明如下:

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的析构函数被调用时,其成员变量number的地址为0。我认为这是因为在析构函数被调用之前,p_instance被释放了。但这种行为并不是我预期的。难道全局变量的析构函数不是在进程退出并且系统尝试释放所有对象时被调用吗?

这是C++,使用cout而不是printf,在main函数中添加return 0;,在default constructor中初始化number,然后再试一次。我对NDK和Android一点也不熟悉,但它仍然是C++。 - Kiril Kirov
4
printf 没有问题。cout 的问题在于它依赖于对象,这些对象可能在您的对象之前被析构。 - Pubby
你尝试过使用GCC的constructordestructor函数属性吗?如果你无法让你的类正常工作,也许这些属性可以帮到你。 - Pubby
2个回答

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

// global variable
ClassP p_instance;

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

添加缺失的分号

在类定义后和类析构函数后都需要添加分号,这样析构函数才能正常运行。

PS 输出结果为 testnumber=0


@Kiril Kirov - 你不能在默认构造函数中初始化变量,这就是为什么它被称为默认构造函数,如果你创建一个构造函数,那么它就被称为无参构造函数。如果你不创建构造函数,那么C++会为你创建一个默认构造函数。只是提供信息。 - Aiden Strydom

2
全局变量在进程关闭或模块/dll卸载时会被销毁。
我猜想你的问题出在如何将你的模块注册到NDK上,听起来你的代码可能没有像你预期那样被声明为全局变量(即它实际上被调用到了一个范围内),或者模块被加载、卸载,然后你的函数被调用了。
查看一下SDK中的一些NDK示例,看看你是否犯了一些非常基本的错误;因为你的代码现在是没问题的。

谢谢您的回复。我会检查一些NDK的样例。顺便说一下,这段代码在使用Linux的PC上运行正常(由g++编译)。 - ccyang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接