考虑以下示例:
#include <iostream>
#include <sstream>
#include <vector>
#include <wchar.h>
#include <stdlib.h>
using namespace std;
struct odp {
int f;
wchar_t* pstr;
};
int main()
{
vector<odp> vec;
ostringstream ss;
wchar_t base[5];
wcscpy_s(base, L"1234");
for (int i = 0; i < 4; i++)
{
odp foo;
foo.f = i;
wchar_t loopStr[1];
foo.pstr = loopStr; // wchar_t* = wchar_t ? Why does this work?
foo.pstr[0] = base[i];
vec.push_back(foo);
}
for (vector<odp>::iterator iter = vec.begin(); iter != vec.end(); iter++)
{
cout << "Vec contains: " << iter->f << ", " << *(iter->pstr) << endl;
}
}
这会产生:
Vec contains: 0, 52
Vec contains: 1, 52
Vec contains: 2, 52
Vec contains: 3, 52
我希望每次 iter->f
和 iter->pstr
都会产生不同的结果。不幸的是,iter->pstr
总是一样的。
我怀疑每次循环都会创建一个新的 loopStr
。我没有将它复制到结构中,而是只复制了一个指针。指针写入的位置正在被覆盖。
我怎样才能避免这种情况?不在堆上分配内存是否可以解决这个问题?
最佳答案
你在这里得到的是未定义的行为。每次通过循环创建和销毁一个数组,然后将其地址分配给 foo.pstr 并将其推回 vector 中。编译器恰好每次都在同一个地方创建该数组(这是合乎逻辑的,但不是必需的)。当您将其打印出来时,从技术上讲,您是在打印出已删除的数据,只是系统不会因为它不是 protected 空间而责备您。内存位置只包含最后分配的内容。
您可以通过停止使用原始字符指针和数组来解决这个问题。
关于C++:指针、循环变量和结构的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3058006/