函数返回结构矢量的副本

Atu*_*tul 3 c++ stl

我在Visual Studio 2010中这样做.

我调用返回结构向量的函数.然后我将第一个向量元素(一个结构)存储到本地结构中,然后访问该结构的字符串成员,我得到正确的值.

但是,如果我通过应用方括号访问相同的字符串值,直接到函数调用本身,我得到垃圾结果.

struct stNameAge
{
    char Name[64];
    int Age;
};

typedef std::vector<stNameAge> NamesAndAges;

NamesAndAges GetNamesAndAges()
{
    stNameAge nameage;
    strcpy_s (nameage.Name, 64, "My name goes here"); 
    nameage.Age = 23; 

    NamesAndAges nameandages;
    nameandages.push_back(nameage);

    return nameandages;
}

int _tmain(int argc, _TCHAR* argv[])
{
    stNameAge nameage = GetNamesAndAges()[0];

    char* MyName1 = nameage.Name ; // I get correct value of name here
    int MyAge1 = nameage.Age ;    // I get correct value here

    char* MyName2 = GetNamesAndAges()[0].Name ; // *** I get garbage value here ***
    int MyAge2 = GetNamesAndAges()[0].Age ; // I get correct value here

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在这里真的很无能为力.有人可以解释为什么会这样吗?

编辑:( 在下面添加了新代码)

如果我保持向量全局,仍然是相同的情况.我相信返回的矢量本身并不是一个好主意.

struct stNameAge
{
    char Name[256];
    int Age;
};

typedef std::vector<stNameAge> NamesAndAges;

NamesAndAges nameandages;

NamesAndAges GetNamesAndAges()
{
    stNameAge nameage;
    strcpy_s (nameage.Name, 64, "My name goes here"); 
    nameage.Age = 23; 

    nameandages.push_back(nameage);

    return nameandages;
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Function returning vector of structs 
    stNameAge nameage = GetNamesAndAges()[0];

    char* MyName2 = GetNamesAndAges()[0].Name ; // *** I get garbage value here ***

    char* MyName1 = nameage.Name ; // I get correct value of name here

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_* A. 5

两者之间存在细微差别,在第一种情况下,您将有效值复制到另一个有效变量,而在第二种情况下,无法保存"结果".

在第一次出现时,您在堆栈上使用临时值来创建向量,但之后您将返回它并将值复制到另一个可以安全使用的变量

stNameAge nameage = GetNamesAndAges()[0];
Run Code Online (Sandbox Code Playgroud)

在第二个你正在创建一个临时向量,请求一个元素,但要求指向该元素的指针.当向量被破坏时,指针不再有效

char* MyName2 = GetNamesAndAges()[0].Name ;
Run Code Online (Sandbox Code Playgroud)

你能看出两种情况之间的区别吗?

在伪代码中,我们可以总结以下内容

int nameage;
int *pointer;
{
  int value = 44; // The value you're interested in

  nameage = value; // You can safely use nameage from this point forward
  pointer = &value; // When the scope ends, there's no guarantee you'll be pointing to valid data
}

// nameage is valid here, pointer is likely not and even if it is it's undefined behavior
Run Code Online (Sandbox Code Playgroud)