簡體   English   中英

向量成員已重置且無法訪問

[英]A vector member is reset and unaccessible

我有兩個項目,一個基本客戶端和一個動態庫。 這是客戶端中發生的情況:

int main()
{
    Scrutinizer scru;
    scru.Scrutinize();
    return 0;
}

在DLL中, Scrutinizer類是這樣的(__declspec(dllexport),為清晰起見,省略了此類)

標頭

class ProcessesGenerator;

    class Scrutinizer
    {
    public:
    Scrutinizer();
    ~Scrutinizer();
    ProcessesGenerator *ProcGenerator
    void Scrutinize();
};

對我來說, ProcessesGenerator的前向聲明是“強制性的”,以避免某種形式的循環引用。

.cpp文件中的構造方法

這是我如何初始化它:

Scrutinizer::Scrutinizer()
{
    ProcGenerator = &ProcessesGenerator();
}

有關此ProcessesGenerator類的更多ProcessesGenerator

標頭

class ProcessesGenerator
{

public:
    ProcessesGenerator();
    ~ProcessesGenerator();
    WinFinder winFinder;
    std::vector<std::string> fooCollec;

    void GenerateProcesses();
};

ProcessesGenerator.cpp

構造函數:

ProcessesGenerator::ProcessesGenerator()
{
    //winFinder = WinFinder();//problem will be the same with or without this line
    fooCollec = std::vector<std::string>{"one", "two", "three"};
}

構造函數中的斷點表明,向量已使用所選值進行了初始化。

有問題的功能:

void ProcessesGenerator::GenerateProcesses() {
    std::string foo = "bar";
    fooCollec = std::vector<std::string>{};//read access violation
    fooCollec.push_back(foo);//read access violation
    winFinder.SomeVector= std::vector<std::string>{};//read access violation
}

到達該位置后,我可以看到vector的大小已重置為0。任何對其進行初始化或推送元素的嘗試都將導致讀取訪問沖突。與WinFinder成員的WinFinder成員相同。 我想這個缺陷很明顯,但是我真的不明白,

謝謝!

你的問題是

Scrutinizer::Scrutinizer()
{
    ProcGenerator = &ProcessesGenerator();
}

您正在做的是獲取一個臨時對象的地址。 該對象將被銷毀,並且該行的末尾,您將得到一個指向有效對象的指針。

解決它的舊方法是使用

Scrutinizer::Scrutinizer()
{
    ProcGenerator = new ProcessesGenerator();
}

但是現在您必須實現復制構造函數,復制分配運算符和析構函數。 由於您擁有現代的編譯器,因此,您可以做的是使ProcGenerator成為std:unique_ptr<ProcessesGenerator> ,然后Scrutinizer()變為

Scrutinizer::Scrutinizer() : ProcGenerator(make_unique<ProcessesGenerator>()) {}

我還想添加&ProcessesGenerator(); 甚至不應該編譯。 不幸的是,MSVS具有非標准擴展名,因此可以對其進行編譯。 您可以打開/Za編譯器選項(強制ANSI兼容性),然后會出現如下錯誤:

錯誤C2102:“&”需要左值

ProcGenerator = &ProcessesGenerator(); 創建一個臨時ProcessesGenerator ,獲取其地址,然后將其放入您的ProcGenerator指針中。 然后將臨時文件銷毀,留下垃圾。

您可能想在堆上分配它ProcGenerator = new ProcessesGenerator; 但即使在那種情況下,我也強烈建議使用unique_ptr而不是原始指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM