C++:指针、循环变量和结构的问题

标签 c++ memory-management pointers loops

考虑以下示例:

#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->fiter->pstr 都会产生不同的结果。不幸的是,iter->pstr 总是一样的。

我怀疑每次循环都会创建一个新的 loopStr。我没有将它复制到结构中,而是只复制了一个指针。指针写入的位置正在被覆盖。

我怎样才能避免这种情况?不在堆上分配内存是否可以解决这个问题?

最佳答案

你在这里得到的是未定义的行为。每次通过循环创建和销毁一个数组,然后将其地址分配给 foo.pstr 并将其推回 vector 中。编译器恰好每次都在同一个地方创建该数组(这是合乎逻辑的,但不是必需的)。当您将其打印出来时,从技术上讲,您是在打印出已删除的数据,只是系统不会因为它不是 protected 空间而责备您。内存位置只包含最后分配的内容。

您可以通过停止使用原始字符指针和数组来解决这个问题。

关于C++:指针、循环变量和结构的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3058006/

相关文章:

c++ - 在没有事件异常的情况下终止调用(多线程合并排序)

c++ - 内存分配/释放错误(极小代码)

c++ - 先调用析构函数再调用构造函数(重置对象)

c - 如果有的话,编译器什么时候会在指针取消引用优化方面保持保守?

c++ - 无法创建由 "Parent"链接的元素列表

c - 奇怪的 free() 无效指针 C

c++ - 如何获取脚本以在 C++ 中插入整个用户输入

c++ - 未解析的外部符号 boost::chrono::system_clock::now(void)

c++ - 将函数指针作为 API 接口(interface)传递给已编译的库

c++ - 更改自动分配内存的范围是否会影响性能?