重载运算符 [ ] 时返回的堆栈内存地址 在下面的评论后编辑:

问题描述

我在为课堂上的问题重载 [] 运算符时遇到了一些问题。这是重载的函数

const char* Person::operator[](const char* str)
{
    if (strcmp(str,"name") == 0)
        return reinterpret_cast<const char *>atoi(name);

    if (strcmp(str,"age") == 0)
    {
        char temp[4];
        _itoa(age,temp,10);
        //cout << temp;
        return temp;
    }
}

类定义如下

class Person
{
private:
    const char* name;
    unsigned int age;
    double height;
    int gradeNo;
    int grades[10];
public:
    Person();
    Person(const char* name,int age,double height);
    void addGrade(int grade);
    const char* operator [] (const char* str);
    operator int();
};

我遇到的问题是运算符重载函数中的 return temp; 行。 CLion 返回以下警告:Address of stack memory associated with local variable 'temp' returned

果然,在尝试使用运算符时,返回的值是一个内存地址。我该如何解决这个问题?和函数的返回类型有关吗?

解决方法

您正在将地址带到临时地址(位于堆栈上),这将使返回的指针几乎立即悬空。

我强烈建议对字符串使用 std::string,不要像使用类一样编写 C++。

然后在此处按值返回 std::string。糟糕的类似 C 的替代方法是在堆上分配字符串并返回它,最好至少作为 std::unique_ptr

在下面的评论后编辑:

由于需要将整数转换为字符串并返回值,因此不能返回临时变量,因此结果必须比方法更有效。基本上有两个不好的选择:

  1. temp 设为静态,这样指针保持有效。缺点是该功能不再可重入。这样更安全,因为它不会泄漏。
const char* foo(int age){
    static char temp[4];
    _itoa(age,temp,10);
    return temp;
}
  1. 返回堆分配的字符串。很大的危险是你让用户释放它:
const char* foo(int age){
    char* temp = new char[256];
    _itoa(age,10);
    return temp;
}

我相信您的代码中也有错别字:

return reinterpret_cast<const char *>atoi(name);

atoi 不应该在那里,对吗?reinterpret_cast 应该不需要。