我对C++的了解是不应该假设全局实例的构造(和析构)的顺序.
当我用编译器std::cout和析构函数中使用的全局实例编写代码时,我遇到了一个问题.
std::cout也是iostream的全局实例.是否std::cout保证在任何其他全局实例之前进行初始化?
我写了一个简单的测试代码,它工作得很好,但我仍然不知道为什么.
#include <iostream>
struct test
{
test() { std::cout << "test::ctor" << std::endl; }
~test() { std::cout << "test::dtor" << std::endl; }
};
test t;
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它打印
test::ctor
Hello world
test::dtor
Run Code Online (Sandbox Code Playgroud)
代码是否有可能无法按预期运行?
在下面的C++代码中,我保证在//更多代码执行后调用~obj()析构函数?或者如果编译器检测到它没有被使用,是否允许编译器更早地销毁它?
{
SomeObject obj;
... // More code
}
Run Code Online (Sandbox Code Playgroud)
我想使用这种技术来节省我必须记住在块的末尾重置一个标志,但我需要为整个块保持设置的标志.
考虑以下库,可以在任何程序执行之前预先加载:
// g++ -std=c++11 -shared -fPIC preload.cpp -o preload.so
// LD_PRELOAD=./preload.so <command>
#include <iostream>
struct Goodbye {
Goodbye() {std::cout << "Hello\n";}
~Goodbye() {std::cout << "Goodbye!\n";}
} goodbye;
Run Code Online (Sandbox Code Playgroud)
问题是,虽然goodbye总是调用全局变量的构造函数,但是没有为某些程序调用析构函数,例如ls:
$ LD_PRELOAD=./preload.so ls
Hello
Run Code Online (Sandbox Code Playgroud)
对于其他一些程序,析构函数按预期调用:
$ LD_PRELOAD=./preload.so man
Hello
What manual page do you want?
Goodbye!
Run Code Online (Sandbox Code Playgroud)
你能解释为什么在第一种情况下没有调用析构函数吗?编辑:上面的问题已经得到解答,那就是程序可能会使用_exit(),abort()来退出.
然而:
有没有办法在预加载的程序退出时强制调用给定的函数?
如果一个类Foo有一个静态成员变量Bar,我希望Bar析构函数只能在析构函数的最后一个实例运行之后才能Foo运行.下面的代码片段不会发生这种情况(gcc 6.3,clang 3.8):
#include <memory>
#include <iostream>
class Foo;
static std::unique_ptr<Foo> foo;
struct Bar {
Bar() {
std::cout << "Bar()" << std::endl;
}
~Bar() {
std::cout << "~Bar()" << std::endl;
}
};
struct Foo {
Foo() {
std::cout << "Foo()" << std::endl;
}
~Foo() {
std::cout << "~Foo()" << std::endl;
}
static Bar bar;
};
Bar Foo::bar;
int main(int argc, char **argv) {
foo = std::make_unique<Foo>();
}
Run Code Online (Sandbox Code Playgroud)
输出:
Bar()
Foo()
~Bar()
~Foo() …Run Code Online (Sandbox Code Playgroud) 当作为引用返回并作为指针直接传递给另一个函数时,静态变量会发生什么?显然,变量在函数返回后仍然存在,但关于这整个概念的一些事情让我感到烦恼.此时是数据后续的内存,被静态变量占用,被释放了吗?当我不再需要它时,运行时会神奇地注意到它,比如某种垃圾收集吗?
举个例子:
SDL_Rect* XSDL_RectConstr(int x, int y, int w, int h)
{
static SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
return ▭
}
void mainLoop()
{
while(isRunning)
{
pollEvents();
SDL_BlitSurface(someSurface, XSDL_RectConstr(0, 0, 100, 100), screen, NULL);
SDL_Flip(screen);
}
}
Run Code Online (Sandbox Code Playgroud)
rectSDL_BlitSurface()返回后会发生什么?我看不出它什么时候会被释放.这不是某种内存泄漏吗?
从Visual Studio DLL调用ITK时内存泄漏的后续问题
我把问题提炼到最简单的例子.
struct A
{
public:
A()
{
mp_data = new int(0x42);
}
~A()
{
delete mp_data;
}
int* mp_data;
};
A a;
Run Code Online (Sandbox Code Playgroud)
在DLL中定义此类全局类时,Visual Studio调试CRT报告在应用程序关闭时泄漏mp_data.除了禁用泄漏报告外,有没有人知道解决方法?
可能重复:
C++中的对象销毁
假设我们有两个类,一个被调用Array,另一个被调用MessageOnExit.
假设Array该类有一个名为的静态数据成员counter.
以下是课程:
class Array {
public:
static int counter;
Array(){counter++;}
~Array(){counter--;}
};
class MessageOnExit {
public:
~MessageOnExit(){cout << Array::counter;}
};
Run Code Online (Sandbox Code Playgroud)
以下是使用这些类的"主要":
// static variable definition
int Array::counter;
// global object definition
MessageOnExit message;
void main() {
Array a1, a2;
Array a3(a1);
}
Run Code Online (Sandbox Code Playgroud)
前两个声明将更改为counter2,然后两次调用Empty/Default构造函数.第三个声明不会更改,counter因为将调用Default复制构造函数.
现在main执行完成后,静态成员的值counter将-1随后是析构函数调用(在a1,a2和a3被去除后),然后message将调用析构函数,打印此值(-1).
我的问题是counter,当message调用析构函数时,我们如何知道静态成员仍然存在且可用.
此外,如果我更改静态/全局对象/变量定义顺序,即message之前定义counter …
如何使用没有Glibc的C中的内联汇编来获取参数值?
我需要这个代码用于Linuxarchecture x86_64和i386.如果你知道MAC OS X或者Windows,也提交并请指导.
void exit(int code)
{
//This function not important!
//...
}
void _start()
{
//How Get arguments value using inline assembly
//in C without Glibc?
//argc
//argv
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
https://gist.github.com/apsun/deccca33244471c1849d29cc6bb5c78e
和
#define ReadRdi(To) asm("movq %%rdi,%0" : "=r"(To));
#define ReadRsi(To) asm("movq %%rsi,%0" : "=r"(To));
long argcL;
long argvL;
ReadRdi(argcL);
ReadRsi(argvL);
int argc = (int) argcL;
//char **argv = (char **) argvL;
exit(argc);
Run Code Online (Sandbox Code Playgroud)
但它仍然返回0.所以这段代码错了!请帮忙.
可能重复:
C++是否为全局和类静态变量调用析构函数?
什么是寿命
MyClass myclass;static MyClass myclass;const MyClass myclass;static const MyClass myclass;static MyClass myclass;在初始化实际发生时函数本地static constexpr MyClass myclass;in C++ 11尤其是它们会在正常程序结束时被销毁(即main没有错误)?标准在哪里如此陈述.
我注意到私有析构函数阻止了所有这些变量的创建.但是,如果我没记错的话,某处已明确提到某些静态数据可能会被放入静态数据部分并加载预先构建的部分.这对我来说意味着不会召唤析构函数.这意味着我可以定义这样一个变量......
c++ ×8
assembly ×1
c ×1
constructor ×1
destructor ×1
gcc ×1
i386 ×1
ld ×1
ld-preload ×1
lifetime ×1
linux ×1
local ×1
memory-leaks ×1
raii ×1
static ×1
x86-64 ×1