我遇到了以下奇怪的情况:我设法有一个全局静态变量与两个实例...这是正常的,或者这是一个编译器中的错误,或者这是一个C++的隐藏领域?下面的复制是一个较大项目的摘录(其行为相同),显然名称已更改以保护罪魁祸首(并且是的,我知道此代码中存在内存泄漏)。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
所以,很明显的问题:
为什么?这怎么可能?有什么东西允许这种行为,或者这是编译器或链接器中的某处的错误吗?
这个“test_class.h”直接位于静态问题的上方,这是一个相当强的指标,它位于标题中,并且命令行提示两个源文件包含它,每个源文件都获得它们自己的'all_alloc'。包含'test_class.h'的每个文件都将获得自己的'all_alloc'。 – WhozCraig
这不是问题,但是以下划线开头的名称后跟大写字母('_OTHER_H_')和包含两个连续下划线的名称将保留给实施。不要使用它们。 –