C++静态变量多个实例
C++ static variable multiple instances
我遇到了以下奇怪的情况:我设法拥有一个带有两个实例的全局静态变量。。。这是正常的,还是编译器中的错误,或者这是C++的隐藏领域?下面的复制品是一个更大项目的摘录(其中的行为是相同的),显然为了保护罪魁祸首而更改了名称(是的,我知道这段代码中存在内存泄漏)。
代码来了:
// other.h
#ifndef _OTHER_H_
#define _OTHER_H_
struct other
{
long longer;
int inter;
char charer;
};
void dosomething();
#endif
和
// other.cpp
#include "other.h"
#include "util.h"
void dosomething()
{
other* something = alloc_mem(other, 4);
}
和
// util.h
#ifndef _UTIL_H_
#define _UTIL_H_
#include <memory.h>
#include <string>
#include "test_class.h"
template <class T> T* allocate(size_t count, const char* f, long l, const char* sth)
{
T* tmp = new T[count];
memset(tmp, 0, count * sizeof(T));
test_class<T*>::instance().throwIn(tmp, f, l, sth, count);
return tmp;
}
#define alloc_mem(type,count) allocate<type>(count, __FILE__, __LINE__, (char*)0)
#endif
和
// main.cpp
#include "other.h"
#include "util.h"
int main()
{
int* i = alloc_mem(int, 1);
int* i1 = alloc_mem(int, 20);
char* c = alloc_mem(char, 1);
dosomething();
int* i3 = alloc_mem(int, 1);
}
主要部分:
// test_class.h
#ifndef test_class_H
#define test_class_H
#include <stdlib.h>
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
static long int all_alloc = 0; // THIS will get linked in two times!
template <typename T>
class test_class
{
private:
test_class() {}
static test_class<T>* pinstance;
public:
~test_class() {}
static test_class& instance() {
if(pinstance == NULL) {
pinstance = new test_class();
}
return *pinstance;
}
void throwIn(T item, const char* file, long line, const char* _compiler, long count) {
int status;
char* s = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status) ;
std::cout << "request:" << sizeof(T) * count << " bytes, type:" << s << " @ "<<
file << ":" << line << " global_addr:" << &all_alloc << std::endl;
all_alloc += sizeof(T) * count ;
free(s);
std::cout<<"All memory:" << all_alloc << std::endl;
}
};
template <class T> test_class<T>* test_class<T>::pinstance = NULL;
#endif
因此,您必须将其编译为:
g++ main.cpp other.cpp -o test
和运行它,和:
$ ./test
request:8 bytes, type:int* @ main.cpp:6 global_addr:0x6022d8
All memory:8
request:160 bytes, type:int* @ main.cpp:7 global_addr:0x6022d8
All memory:168
request:8 bytes, type:char* @ main.cpp:8 global_addr:0x6022d8
All memory:176
request:32 bytes, type:other* @ other.cpp:6 global_addr:0x6022f8
All memory:32
request:8 bytes, type:int* @ main.cpp:11 global_addr:0x6022d8
All memory:184
所以,正如我所看到的,我有两个all_alloc
的全局地址。。。事实上,nm -C test
显示:
00000000006022d8 b all_alloc
00000000006022f8 b all_alloc
所以,很明显的问题是:
为什么?这怎么可能?是否有允许这种行为的东西,或者这是编译器或链接器中的某个错误?
在这种情况下,我认为您不想声明您的all_alloc
静态。在这种情况下,这意味着链接是内部的。在您的情况下,您将获得两个副本,因为两个文件都包含标头。
如果删除static
,则会有两个冲突的副本,并导致链接器错误。这不好。
我相信您想要做的是将static
更改为extern
,然后在一个cpp文件中定义变量及其值。
标题:
extern long int all_alloc;
cpp:
long int all_alloc = 0;
这将提供all_alloc
的一个副本,供您的代码共享。
当你有全局变量时,它已经有了静态持续时间,所以static
关键字对它来说意味着不同。当你在文件中有类定义时,你定义了全局静态变量,我假设它是一个头。为什么在标题中使用静态全局变量是个坏主意,以及您将得到什么,您可以在这里阅读所以答案是:这是预期的行为,而不是bug。
相关文章:
- 返回 C++ 中的指针实例变量
- 返回实例变量的c++方法可以访问变量中的数据,但不能更改它,但在编译时不会生成错误
- C++ 实例变量初始值设定项中的重复类型
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- C++ 中实例变量的双冒号
- 我可以在没有任何实例变量的情况下使用 decltype 吗?
- OpenMP 私有类实例变量
- C 取消实例变量指针
- 在C++私有区域中初始化实例变量
- 如何将指针存储在实例变量中,该指针被声明为指向基类的指针
- 如何在Arduino中创建另一个类库的实例变量
- 单元测试呼叫实例变量的函数
- 为构造函数初始化引用实例变量提供默认值
- 如何使编译器在实例变量未初始化时C++生成错误或警告
- 如何超载分配运算符,该操作员总计两个实例变量
- C++:通过引用传递或使用私有实例变量
- 对象作为类内的实例变量
- 在不构造实例变量的情况下C++声明实例变量的好方法是什么?
- 实例变量列表中的对象未被保留?指针问题
- Asio完成处理程序中的实例变量无效