【问题标题】:Why does my struct lose the string value even with references?为什么我的结构即使有引用也会丢失字符串值?
【发布时间】:2019-06-13 19:05:50
【问题描述】:
struct Word {

    string wordName; //loses its value
    vector<string> contents; //irrelevant for the question
    int numContents = 0; //maintains its value

};

vector<Word*> wordMsgs;

int main()
{

vector<string> result;
result.push_back("wordName");
result.push_back("shouldEnterIf");

Word curr;
        //New Word
        if (result[1] != "") {
            Word w;
            w.numContents = 10; //just a testing #, suppose to represent size of vector
            wordMsgs.push_back(&w);


            w.wordName = result[0]; //name of Word


            //here w.wordName and (*wordMsgs[0]).wordName display the same string; result[0] 
            curr = w;
        }
        //here curr.wordName displays result[0] but (*wordMsgs[0]).wordName doesn't. However, (*wordMsgs[0]).numContents returns 10 as expected
}
}

所以我有一个结构引用向量,假设向量的 push_back() 方法仅将副本推送到向量的末尾。我创建了一个 Word 结构的实例,并将该引用放入我的向量 wordMsgs 中。然后我编辑它指向的结构,然后我的字符串变量在离开 if 语句时丢失了!但是,我的 int 变量永远不会失去它的价值。 我不明白,因为我使用了指针(而且我在 C++ 中,所以我认为字符串没问题)而且我不认为这是一个局部变量问题......

【问题讨论】:

标签: c++ string struct


【解决方案1】:

变量w在:

    if (...) {
        Word w;
        wordMsgs.push_back(&w);
        ...
    }

if 语句范围内的堆栈上分配。

然后您将其地址添加到您的指针向量中。

一旦在if 语句之外,该变量将被释放,并且该地址处的值不再是“实心”,因此您在该向量中基本上有一个“垃圾地址”。

从这里开始,您的程序的行为大多是不可预测的......

【讨论】:

  • “从这里开始,你的程序的行为大多是不可预测的......”嗯,这就是所谓的未定义的行为。因此,我们已经对这种情况有了一个标准定义。
  • 建议添加解决方案,例如将vector&lt;Word*&gt; wordMsgs;更改为vector&lt;Word&gt; wordMsgs;并完全丢弃指针
【解决方案2】:

以下是代码中出现问题的最小示例:

#include <string>
#include <vector>
#include <iostream>

int main() {
   std::vector<string*> words;     // why pointers?

   if (true) {                    // scope starts here
       std::string word = "muh";   
       words.push_back(&word);    // dont do that !!
   }                              // scope ends here

   std::cout << *words.back(); 
}

当您通过取消引用指针访问字符串时,字符串早已不复存在,因为word 在超出范围时被销毁。取消引用指针是undefined behaviour。当你不需要时,你不应该在向量中有原始指针。你可能想要这样的东西:

#include <string>
#include <vector>
#include <iostream>

int main() {
   std::vector<string> words;

   if (true) {               
       std::string word = "muh";   
       words.push_back(word);      // vector stores a copy ! and manages lifetime of its elements
   }                         

   std::cout << words.back(); 
}

【讨论】:

    【解决方案3】:

    你有一个指针向量,而不是引用。当您使用 &amp;w 推回本地定义的结构 Wors w 的地址时,当您退出 if 语句时,您将直接丢失该数据。您需要为向量分配和释放内存。最好将对象推送到向量中或使用智能指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多