简体   繁体   English

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

[英]Multiple New Objects Have The Same Pointer Addresses

I'm relatively new to C++ so I apologize right away if this is a stupid question but I can't for the life of me seem to figure out whats going on. 我是C ++的新手,所以如果这是一个愚蠢的问题,我会立即道歉,但是我似乎一辈子都无法弄清楚发生了什么。 Essentially, I enter a helper function that creates objects, and then returns a pointer to each object. 本质上,我输入一个创建对象的助手函数,然后返回指向每个对象的指针。 Its works okay, but the issue that is popping up is that sometimes, the pointer values are identical to the last iteration of the function call. 它可以正常工作,但是弹出的问题是有时指针值与函数调用的最后一次迭代相同。

For example: 例如:

I'll often see something ... 我会经常看到一些东西...

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

Is this undefined behaviour? 这是不确定的行为吗? I would very, very much appreciate any and all help! 我将非常非常感谢您的帮助!

The pointers are the return values of this helper function (sorry its a bit verbose): 指针是此辅助函数的返回值(抱歉,它有点冗长):

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;

}

The problems exist at these lines: 这些问题存在于以下行:

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

For some reason the pointer value of &email seems to be the same as the last iteration instead being a new pointer value. 由于某些原因,&email的指针值似乎与上一次迭代相同,而不是新的指针值。 The same issue exists in the other return points of the function. 函数的其他返回点中存在相同的问题。

'iMessage message' is an abstract base class. “ iMessage消息”是抽象的基类。

You are creating your objects on the stack and returning them. 您正在堆栈上创建对象并返回它们。 This is a bad thing to do as the object on the stack will a) be destroyed when the scope in which it is created is left and b) the memory that you're returning isn't yours to return. 这是一件不好的事情,因为堆栈上的对象将a)在创建它的作用域被保留时被销毁,并且b)您要返回的内存不是您要返回的。

You need to allocate the objects to return on the heap and return them by pointer and then clean them up when you are done with them. 您需要分配对象以在堆上返回并通过指针返回它们,然后在完成处理后将其清理。 You may wish to consider returning some kind of smart pointer to manage the lifetime of the dynamic memory that you're allocating. 您可能希望考虑返回某种智能指针来管理分配的动态内存的生命周期。

So, instead of 所以,代替

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

You want to do this: 您想这样做:

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

    return message;

The reason that your current implementation sometimes displays the same memory addresses is simply because the objects happen to be being created in the same place on the stack. 当前实现有时显示相同的内存地址的原因仅是因为恰好在堆栈的同一位置创建了对象。 The bug is that you're returning pointers to these stack based objects rather than allocating on the heap and returning an object that can outlive the function call. 错误是您要返回指向这些基于堆栈的对象的指针,而不是在堆上分配并返回可以超出函数调用寿命的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM