我在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;
}
我在这里真的很无能为力。有人可以解释为什么会这样吗?
已编辑: (已添加以下新代码)
如果我保持矢量全局,那么它仍然是相同的情况。我相信返回的矢量本身并不是一个好主意。
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;
}
答案 0 :(得分:5)
两者之间存在细微差别,在第一种情况下,您将有效值复制到另一个有效变量,而在第二种情况下,无法保存&#34;结果&# 34。
在第一次出现时,您使用堆栈上的临时值来创建向量,然后您将其返回并复制 - 将值分配给您可以安全使用的另一个变量
stNameAge nameage = GetNamesAndAges()[0];
在第二步中你要创建一个临时向量,请求一个元素,但要求指向该元素的指针。当向量被破坏时,指针不再有效
char* MyName2 = GetNamesAndAges()[0].Name ;
你能看出两种情况之间的区别吗?
在伪代码中,我们可以用以下内容进行总结
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
答案 1 :(得分:3)
当你这样写:
stNameAge nameage = GetNamesAndAges()[0];
返回的对象(因为它是函数的本地对象)被销毁,但在销毁之前,第一个对象(来自向量)被复制到nameage
变量。这就是它运作的原因。
然而,当你写:
char* MyName2 = GetNamesAndAges()[0].Name;
这里,由于Name
是一个指针,它仍然指向不再属于该程序的同一地址(因为返回的对象被销毁)。所以MyName2
指向被破坏的对象。
int MyAge2 = GetNamesAndAges()[0].Age ;
与第一名相同。该对象是复制。
在所有情况下,都会发生 copy 。那么为什么第二个不起作用,而是第一个和第三个工作?好吧,因为当指针被复制时,它仍然指向同一个对象 - 指针所指向的对象不被复制,所以在第二种情况下,对象(由指针指向) )被销毁,但复制指针仍然指向它。