Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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++_Pointers_Set_Elements_Stdvector - Fatal编程技术网

C++ 字符串和商店

C++ 字符串和商店,c++,pointers,set,elements,stdvector,C++,Pointers,Set,Elements,Stdvector,在下面的程序中,一个字符串被添加到一个空存储中。然后,该存储元素的地址存储在指针“s1”中。然后添加另一个字符串,这会以某种方式导致指向原始元素的指针失败 #include <iostream> #include <string> #include <vector> class store2 { public: void add(std::string s) {words.push_back(s); last_added2 = &am

在下面的程序中,一个字符串被添加到一个空存储中。然后,该存储元素的地址存储在指针“s1”中。然后添加另一个字符串,这会以某种方式导致指向原始元素的指针失败

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

class store2
{
    public:
        void add(std::string s) {words.push_back(s); last_added2 = &words.at(words.size() - 1);}
        std::string* last_added() {return last_added2;}

    private:
        std::string* last_added2;
        std::vector<std::string> words;
};

void main()
{
    store2 store;
    store.add("one");
    std::string* s1 = store.last_added();
    std::cout<<*s1<<std::endl;
    store.add("two");
    std::cout<<*s1<<std::endl; // crash
}
#包括
#包括
#包括
二级仓库
{
公众:
void add(std::string s){words.push_back(s);last_added2=&words.at(words.size()-1);}
std::string*last_added(){return last_added2;}
私人:
std::string*最后添加的2;
向量词;
};
void main()
{
商店2;
储存。添加(“一”);
std::string*s1=store.last_added();

std::cout当您向
std::vector
添加新项时,该向量可能需要扩展其缓冲区,这样做可能会将缓冲区移动到不同的内存区域。因此,指向其元素的指针将无效。简而言之,在调整向量大小后,指向向量项的指针不保证有效如果向量没有足够的保留空间,d
push_back
可能会调整向量大小


您可以在开始时为向量保留空间,但之后可以分配到向量中的项数会受到限制。

如果需要确保集合中的指针保持有效,您可能需要向量以外的其他对象(例如,您可以使用
std::deque
std::list
——通常两者之间首选
std::deque


或者,您可以返回字符串的索引,并提供一个成员函数,在使用向量时将其索引到向量中,而不是返回指针(通常是一个糟糕的主意)。修改向量的内容时,向量的迭代器可能会失效。请参阅

如果确实希望保留现有接口并保留插入向量的元素的指针,则可以按指针而不是按值存储字符串,例如:

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

class store2
{
public:
    store2 ()
    {
    }

    ~store2 ()
    {
        for (std::vector<std::string *>::iterator it =
                 words.begin (), end_it = words.end ();
             it != end_it; ++it)
        {
            delete *it;
        }
        words.clear ();
    }

    void add (const std::string & s)
    {
        std::auto_ptr<std::string> v (new std::string (s));
        words.push_back (v.get ());
        v.release ();
    }

    std::string *last_added ()
    {
        return words.back ();
    }

    const std::string *last_added () const
    {
        return words.back ();
    }

private:
    std::vector<std::string *> words;
};

int main ()
{
    store2 store;
    store.add("one");
    std::string* s1 = store.last_added();
    std::cout<<*s1<<std::endl;
    store.add("two");
    std::cout<<*s1<<std::endl; // no crash :-)
}
#包括
#包括
#包括
#包括
二级仓库
{
公众:
仓库2()
{
}
~2()
{
for(std::vector::iterator)=
words.begin(),end_it=words.end();
它!=结束它;++它)
{
删除*它;
}
words.clear();
}
void add(const std::string&s)
{
std::auto_ptr v(新的std::字符串);
推回(v.get());
v、 释放();
}
std::string*上次添加()
{
返回words.back();
}
const std::string*最后添加()const
{
返回words.back();
}
私人:
向量词;
};
int main()
{
商店2;
储存。添加(“一”);
std::string*s1=store.last_added();

std::cout您有什么特别的原因想使用指针(heap)吗? 如果没有,就做:

   class store2
    {
        public:
            void add(std::string s) {words.push_back(s);}
            std::string last_added() { if (words.size() == 0) return "";
return words[words.size()-1];}

        private:
            std::vector<std::string> words;
    }
类存储2
{
公众:
void add(std::string s){words.push_back(s);}
std::string last_added(){if(words.size()==0)返回“”;
返回单词[words.size()-1];}
私人:
向量词;
}

它不需要是std::vector,许多std::vector功能都不是必需的,但它确实需要调整大小,元素确实需要可靠的寻址。如果不需要随机访问,可以使用
std::list
访问列表中最近添加的项,并保留单个元素的地址是的,列表允许您访问
O(1)
中的第一个和最后一个元素。太棒了。我看不出任何问题。我使用的是std::list words;和{words.push_back(v);last_added2=&words.back();}+1,这是一种显而易见的方式,不会保存可能失效的临时表(或者使用
words.back()
)。我需要返回指向元素的指针,而不是元素的副本。谢谢。但我将使用peoro的解决方案,其中包括列表。这是一种非常复杂的方法。如果它能够工作,这是一个很好的答案,因为它保留了向量的使用和存储的接口。使用索引号是一个好主意,但对于更大的pr来说不起作用这是一个简化的问题。我正在使用您和peoro的std::list解决方案。