c++ - 多个新对象具有相同的指针地址

标签 c++

我是 C++ 的新手,所以如果这是一个愚蠢的问题,我马上道歉,但我似乎无法弄清楚发生了什么。本质上,我输入了一个创建对象的辅助函数,然后返回指向每个对象的指针。它工作正常,但出现的问题是有时指针值与函数调用的最后一次迭代相同。

例如:

我会经常看到一些东西......

0x7fff5d1d0f10
0x7fff5d1d0d80
0x7fff5d1d0d80 <- same as the last pointer
0x7fff5d1d0fe0
0x7fff5d1d0fe0 <- same as the last pointer

这是未定义的行为吗?我非常非常感谢任何帮助!

指针是这个辅助函数的返回值(抱歉有点冗长):

w5::iMessage* w5::getMessage(std::ifstream& file, char limiter){

    std::string result;

    int line_no = 0;

    std::string line;
    while (getline(file, line)){
        if(line[0] == 'T' or line[0] == 'e'){
            iMessage * message;
            message = nullptr;
            std::string user = "";
            std::string reply = "";
            std::string tweet = "";

            if (line[0] == 'T'){
                int length = line.length();
                int _user = line.find("T");
                int _reply = line.find("@");
                if(_reply != std::string::npos){
                    int first_space = line.find_first_of(" ");
                    int second_space = line.find_first_of(" ", _reply);
                    //user
                    //std::cout << line.substr(_user+1, _reply-2) << std::endl;
                    user = line.substr(_user+1, _reply-2);
                    //reply
                    // std::cout << line.substr(_reply+1, second_space-_reply)  << std::endl;
                    reply = line.substr(_reply+1, second_space-_reply);
                    //tweet
                    //std::cout << line.substr(second_space+1)  << std::endl;
                    tweet = line.substr(second_space+1);
                    Twitter twitter(user, tweet, reply);
                    // std::cout << &twitter << std::endl;
                    message = &twitter;
                    // std::cout << message << std::endl;
                    return message;

                }else{
                    int _tweet = line.find(" ");

                    //user
                    //std::cout << line.substr(_user+1, _tweet) << std::endl;
                    std::string user = line.substr(_user+1, _tweet);

                    //tweet
                    if(_tweet != std::string::npos){
                        // std::cout << line.substr(_tweet+1)  << std::endl;
                        std::string tweet = line.substr(_tweet+1);
                        if(tweet != ""){
                            Twitter twitter(user, tweet, "");
                            iMessage * message;
                            // std::cout << &twitter << std::endl;
                            message = &twitter;
                            // std::cout << message << std::endl;
                            return message;
                        }
                    }
                }


            }

            if(line[0] == 'e'){
                int length = line.length();
                int _from = line.find("From:");
                int _to = line.find(" To:");
                int _date = line.find(" Date:");
                int _body = line.find(" Body:");
                std::string to = "";
                std::string from = "";
                std::string date = "";
                std::string body = "";
                //from
                //std::cout << line.substr(_from+5, _to-_from-4) << std::endl;
                to = line.substr(_from+5, _to-_from-4);
                //to
                // std::cout << line.substr(_to+4, _date-_to-3) << std::endl;
                from = line.substr(_to+4, _date-_to-3);
                //date
                // std::cout << line.substr(_date+6, _body-_date-6) << std::endl;
                date = line.substr(_date+6, _body-_date-6);
                //body
                // std::cout << line.substr(_body+6) << std::endl;
                body = line.substr(_body+6);
                Email email(from, to, body, date);
                // std::cout << &email << std::endl;
                message = &email;
                // std::cout << message << std::endl;
                return message;
            }

            result += line + "\n";
            line_no++;
        }
    }

    iMessage *message;
    message = nullptr;
    return message;

}

问题存在于这几行:

        Email email(from, to, body, date);
        // std::cout << &email << std::endl;
        message = &email;
        // std::cout << message << std::endl;
        return message;

出于某种原因,&email 的指针值似乎与上一次迭代相同,而不是新的指针值。该函数的其他返回点也存在同样的问题。

'iMessage 消息'是一个抽象基类。

最佳答案

您正在堆栈上创建对象并返回它们。这是一件坏事,因为堆栈上的对象将 a) 在创建它的范围离开时被销毁,并且 b) 您返回的内存不属于您。

您需要分配对象以在堆上返回并通过指针返回它们,然后在完成后清理它们。您可能希望考虑返回某种智能指针来管理您正在分配的动态内存的生命周期。

所以,而不是

    Email email(from, to, body, date);
    // std::cout << &email << std::endl;
    message = &email;
    // std::cout << message << std::endl;
    return message;

你想这样做:

    message = new Email(from, to, body, date);

    return message;

您当前的实现有时显示相同内存地址的原因很简单,因为对象恰好是在堆栈的同一位置创建的。错误在于您要返回指向这些基于堆栈的对象的指针,而不是在堆上进行分配并返回一个可以比函数调用更有效的对象。

关于c++ - 多个新对象具有相同的指针地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26552476/

相关文章:

c++ - 通过模板中的成员函数指针对 shared_ptr 的成员函数调用

c++ - 如何在 C++ 中删除集合或如何将集合的大小调整为 0

c++ - 没有创建基类的对象时如何访问虚函数内容

c++ - 如何使用C编程创建图像数据库?

c++ - 为什么 (int )'\xff' != 0xff 但 (int )'\x7f' == 0x7f?

python - python 中的 c++ map<int, int>

c++ - 在 C++ 中打印二维数组

c++ - cpp程序在访问类成员的成员变量时挂起

c++ - 尝试使用 vector 数组来实现图

c++ - 为什么从 char*** 到 char*const** 的转换无效?