推入向量后,内存已损坏

sre*_*ree 1 c++ linux stl

为什么在推入向量后内存被破坏了.在下面的程序中,我有一个带字符串var的结构(它不是指针).我每次创建一个本地struct对象并分配一个字符串值并推送到向量.在推送到向量后,我正在对本地struct对象进行更改.但是这种变化正在向量结构对象的字符串数据中反映出来.

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

    using namespace std;

    void PushVector(string);

    struct thread_info
    {
            int  id;
            string threadname;
            bool bval;
    };

    std::vector<thread_info> myvector;


    int main ()
    {
            PushVector("Thread1"); // valid data into vector
            PushVector("Thread2");

            struct thread_info print;

            while(!myvector.empty())
            {
                    for(unsigned int index = 0; index < myvector.size(); ++index )
                    {
                            print = myvector.at(index);
                            cout<<"id : "<<print.id<<"\nthread name : "<<print.threadname<<"\nbool value : "<<print.bval<<endl;
                    }
                    myvector.clear();
            }
            return 0;
    }

    void PushVector(const string str)
    {

            std::cout << "Push the thread name to vector\n";
            struct thread_info thread;
            thread.id = 10;
            thread.threadname = str;
            thread.bval = true;
            myvector.push_back (thread); //copying struct obj to vector
            char* p =  (char* )thread.threadname.c_str();
            memcpy(p,"Wrong", 5); //==> Memory corrupting with invalid data after push back. Is it a limitation in C++? 
            thread.threadname = "blabla";  //trying to corrupt directly to string object
    }
Run Code Online (Sandbox Code Playgroud)

o/p:将线程名称
推送到向量将线程名称推送到向量
ID:10
线程名称:Wrongd1 ==>内存已损坏?为什么没有blabla字符串?
bool值:1
id:10个
线程名称:Wrongd2 ==>内存已损坏?为什么没有blabla字符串?
bool值:1

Lig*_*ica 5

memcpy结果.c_str()错误的.事实上,你必须const用一个演员而不是暗示来破坏它吗?哪种学习资源教会你这样做?

作为paulm所以说得好:

像这样在字符串的记忆中踩踏只会导致眼泪.

std::string::c_str()返回指向您不应修改的常量缓冲区的指针; 由于某些工具链中存在某些优化(例如GCC中的SSO <5.0),它甚至可能不是真正的底层缓冲区,这在这里似乎就是这种情况.

忘了memcpy; 这不是C.

最好的,你可以这样做:

thread.threadname.resize(5);
memcpy(&thread.threadname[0], "Wrong", 5);
Run Code Online (Sandbox Code Playgroud)

或者,在C++代码中:

thread.threadname.resize(5);
std::copy("Wrong", "Wrong"+5, &thread.threadname[0]);
Run Code Online (Sandbox Code Playgroud)

但是,对于实际,你应该写:

thread.threadname = "Wrong";
Run Code Online (Sandbox Code Playgroud)