Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;静态变量多实例_C++_Templates_Static_Linker_G++ - Fatal编程技术网

C++ C++;静态变量多实例

C++ C++;静态变量多实例,c++,templates,static,linker,g++,C++,Templates,Static,Linker,G++,我遇到了以下奇怪的情况:我设法得到了一个带有两个实例的全局静态变量。。。这是正常的还是这是编译器中的一个bug或者是C++的隐藏领域?下面的复制品是从一个更大的项目(行为相同)中提取的,显然名称被更改以保护罪犯(是的,我知道这段代码中存在内存泄漏) 下面是代码: // other.h #ifndef _OTHER_H_ #define _OTHER_H_ struct other { long longer; int inter; char charer; }; vo

我遇到了以下奇怪的情况:我设法得到了一个带有两个实例的全局静态变量。。。这是正常的还是这是编译器中的一个bug或者是C++的隐藏领域?下面的复制品是从一个更大的项目(行为相同)中提取的,显然名称被更改以保护罪犯(是的,我知道这段代码中存在内存泄漏)

下面是代码:

// other.h
#ifndef _OTHER_H_
#define _OTHER_H_

struct other
{
    long longer;
    int inter;
    char charer;
};

void dosomething();

#endif

以及主要部分:

// 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
然后运行它,然后:

$ ./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\u alloc
。。。实际上,
nm-C测试显示:

00000000006022d8 b all_alloc
00000000006022f8 b all_alloc
因此,很明显,问题是:


为什么??这怎么可能?是否存在允许这种行为的东西,或者这是编译器或链接器中的某个错误

当您有全局变量时,它已经有了静态持续时间,所以
static
关键字对它意味着不同的含义。由于文件中有类定义,所以定义了全局静态变量,我假设它是一个头。为什么在页眉中使用静态全局变量是个坏主意,并且您可以读取得到的内容
所以答案是:这是预期的行为,而不是bug。

在这种情况下,我认为您不想声明您的
所有alloc
静态。在这种情况下,这意味着连杆是内部的。在您的例子中,由于两个文件包含头,所以您将获得两个副本

如果删除
静态
,则会有两个副本冲突,并导致链接器错误。这不好

我相信您要做的是将
static
更改为
extern
,然后在一个cpp文件中定义变量及其值

标题:

extern long int all_alloc;
cpp:


这将提供一个在代码之间共享的
all\u alloc
副本。

此“test\u class.h”直接位于静态问题上方,是一个相当强的指示器,它位于标题中,并且您的命令行建议包含两个源文件,每个源文件都有自己的
all\u alloc
。包含
test\u class.h
的每个文件都将获得它们自己的
all\u alloc
。这不是问题所在,但以下划线开头,后跟大写字母(
\u OTHER\u h
)的名称以及包含两个连续下划线的名称将保留给实现。不要使用它们。
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
00000000006022d8 b all_alloc
00000000006022f8 b all_alloc
extern long int all_alloc;
long int all_alloc = 0;