C++ 指向向量中项目的指针不稳定。

C++ 指向向量中项目的指针不稳定。,c++,class,struct,C++,Class,Struct,我观察到一些非常奇怪的行为。以下是最简单的例子: #include <iostream> #include <vector> #include <stdexcept> #include "sparsepp.h" enum Version { hg19, hg38 }; enum Base { A, T, G, C }; typedef struct { Base ref; float

我观察到一些非常奇怪的行为。以下是最简单的例子:

#include <iostream>
#include <vector>
#include <stdexcept>
#include "sparsepp.h"


enum Version {
    hg19,
    hg38
};


enum Base {
    A,
    T,
    G,
    C
};


typedef struct {
    Base ref;
    float a;
    float c;
    float g;
    float t;
} SNV;



class GenomeMap {

private:
    spp::sparse_hash_map<long, SNV*> * hg19_mapping;
    spp::sparse_hash_map<long, SNV*> * hg38_mapping;
    std::vector<SNV> values;

public:
    GenomeMap() {

        hg19_mapping = new spp::sparse_hash_map<long, SNV*>;
        hg38_mapping = new spp::sparse_hash_map<long, SNV*>;

    }

    void add(long hg19pos, long hg38pos, SNV value) {
        values.push_back(value);
        (*hg19_mapping)[hg19pos] = &(values.back());
        (*hg38_mapping)[hg38pos] = &(values.back());
    }

    float get(Version version, long position, Base ref, Base alt) {
        spp::sparse_hash_map<long, SNV*> * mapping = (version == hg19) ? hg19_mapping : hg38_mapping;
        SNV* value = (*mapping)[position];

        if (!value || ref != value->ref)
            return -1;

        switch (alt) {
            case A:
                return value->a;
            case C:
                return value->c;
            case G:
                return value->g;
            case T:
                return value->t;
        }
        throw std::invalid_argument("Invalid arguments");
    }

    ~GenomeMap() {
        delete this->hg19_mapping;
        delete this->hg38_mapping;
    }
};


int main(void) {
    SNV value = {A, 0.1, 0.2, -1.0, 0.3};

    GenomeMap mapping;
    mapping.add(1, 2, value);
    mapping.add(2, 3, value);
    std::cout << mapping.get(hg19, 1, A, T) << "\n";
    std::cout << mapping.get(hg19, 1, A, T) << "\n";
    std::cout << mapping.get(hg19, 2, T, G) << "\n";
    std::cout << mapping.get(hg19, 2, A, G) << "\n";
    std::cout << mapping.get(hg38, 1, A, T) << "\n";
    std::cout << mapping.get(hg38, 1, A, T) << "\n";
    std::cout << mapping.get(hg38, 2, T, G) << "\n";
    std::cout << mapping.get(hg38, 2, A, G) << "\n";

    return 0;

}
大多数情况下,我会:

0.3
0
-1
-1.1
-1
-1
-1
1.4013e-45
偶尔,第二行是
0.3
。我相信,我错过了一些非常愚蠢的事情。我尝试用STL中的
std::map
替换
sparse\u hash\u map
,但没有任何改变

你的问题是

void add(long hg19pos, long hg38pos, SNV value) {
    values.push_back(value);                 // <<<<======= HERE
    (*hg19_mapping)[hg19pos] = &(values.back());
    (*hg38_mapping)[hg38pos] = &(values.back());
}
void add(长HG19位、长HG38位、SNV值){
值。向后推(值);//您的问题是

void add(long hg19pos, long hg38pos, SNV value) {
    values.push_back(value);                 // <<<<======= HERE
    (*hg19_mapping)[hg19pos] = &(values.back());
    (*hg38_mapping)[hg38pos] = &(values.back());
}
void add(长HG19位、长HG38位、SNV值){

value.push_back(value);//为什么不使用智能指针(例如
std::unique_ptr
)作为值?@πάνταῥεῖ 我已经在C++的一个严格的C兼容子集中编码了很长时间,所以我不知道什么是代码> STD::UnQuyJPPT/<代码>。我不再有这个限制了。这里,你不要把指针存储到向量的元素中。当底层存储重新分配时,它们就变得无效。/code>返回一个引用,而不是一个副本。为什么不使用智能指针(例如
std::unique_ptr
)作为值?@πνταῥεῖ 我已经在C++的一个严格的C兼容子集中编码了很长时间,所以我不知道什么是代码> STD::UnQuyJPPT/<代码>。我不再有这个限制了。这里,你不要把指针存储到向量的元素中。当底层存储重新分配时,它们就变得无效。/代码>返回引用,而不是副本。非常感谢。将索引存储为
insigned long
甚至比存储64位指针更节省内存。只有在64位windows上。在所有其他平台上(实际上)long和pointer的大小相同。请多多留意。将索引存储为
insigned long
甚至比存储64位指针的内存效率更高。只有在64位windows上。在所有其他平台上(实际上),long和pointer的大小相同