Std::vector 被初始化为垃圾。奇怪的行为。有啥想法吗?

Posted

技术标签:

【中文标题】Std::vector 被初始化为垃圾。奇怪的行为。有啥想法吗?【英文标题】:Std::vector is initialized to garbage. Weird behavior. Any ideas on what's up?Std::vector 被初始化为垃圾。奇怪的行为。有什么想法吗? 【发布时间】:2009-09-17 05:58:02 【问题描述】:

我的班级有这个成员。

  std::vector<AvaWrapper> m_controls;

在我的构造函数中调用

  m_controls.clear()

然后我调用了一个成员函数,该函数再次执行 m_controls.clear() 但它因断言而崩溃。调试器显示 m_controls 有 50 万个或更多条目,尽管它们都不是有效的,因为当我展开树时调试器显示“错误:无法评估表达式”。所以,我的直觉是这个类没有正确创建,因为这段代码确实有效,但我后来从这个类派生了一个类,我调用 new() 来创建父类。在它作为基类的新角色中,它正在爆炸。然而,this 指针显示所有其他成员变量都有有效数据,所以我的预感是错误的。构造函数也被调用。有任何想法吗?谢谢。

更新2:

Train::Train() : SpriteWindowFrame(200)

  s_mutexProtectingTheGlobalData = new wxMutex();
  m_window_rect = NULL;
  m_thread = NULL;
  m_ok = false;
  m_accumulate_timer = new wxTimer();
  m_accumulate_timer->SetOwner(this, ACCUMULATE_TIMER_ID);

  m_autohide_timer = new wxTimer();
  m_autohide_timer->SetOwner(this, AUTOHIDE_TIMER_ID);

  m_autohide = false;
  m_autohide_period = 5000;
  m_controls.clear();

更新:

//This version works.
SpaceInit::SpaceInit()

  //Use INI config store. If you need something else, just
  //create the appropriate object.
  m_config_store = new IniConfigStore();

  //Start up config. 
  Init(); 

  m_t = new Trains();
  return;


SpaceInit::~SpaceInit()

  wxDELETE(m_config_store);
  return;

我可以这样做: m_t->SomeMemberFunctionThatManipulatesVector()

它有效。

这个没有

SpaceInit::SpaceInit():Trains()

  //Use INI config store. If you need something else, just
  //create the appropriate object.
  m_config_store = new IniConfigStore();

  //Start up config. 
  Init(); 
  return;

我做不到: SomeMemberFunctionThatManipulatesVector()

在矢量上爆炸。

我刚刚注意到 this 指针在 Train() 默认构造函数中确实搞砸了。我以为不是,但它是。 Trains 构造函数运行 但一切都被破坏了。

我的 Trains 构造函数代码运行正常。只需初始化一些东西,新建一些东西,等等。 SpaceInit 是用 SpaceInit* t = new SpaceInit(); 创建的。 Train 是一个派生类,所以可能与它有关?

【问题讨论】:

能否给我们头文件和所有相关代码? std::vector 的模板参数是什么?这可能会给我们一个线索。 你需要给我们更多的代码。您的简化还不够,而且是错误的。您不可能拥有成员 std::vector m_controls;,因为这不是 vector 的有效用法。 我会尝试发布更多代码,但 GMan 我不知道你在说什么。如图所示,我有大量使用矢量成员函数的类。 为什么人们认为他们对问题的英文描述比源代码更能激发程序员解决问题。 【参考方案1】:

这个说法有问题:

我后来从这个类派生了一个类,我调用 new() 来创建父类。

当你从一个类派生时,你不会调用 new() 来创建一个父类。在子构造函数的第一行运行之前,已经调用了父构造函数。

我怀疑您的问题可能与该区域有关。也许您可以向我们展示发生这种情况的代码。

【讨论】:

+1 为我提供了第一次诊断而没有大喊“GIEV CODE!”。特别是,对问题的“给我所有相关代码”评论是没有用的,因为问题的创建者可能不知道什么是相关的,什么不是。【参考方案2】:

因为您似乎有 RAW 指针(很难说,因为我们没有 SpaceInit 的定义)。您是否定义了复制构造函数和赋值运算符。如果不是,您可能会访问已销毁的对象,这会导致未定义的行为,包括覆盖其他成员。

【讨论】:

没有。我没有太多重载这些运算符的经验。为什么需要这样做?我不是在克隆或复制对象。 有很多操作会导致不明显的对象被复制。如果您确定它们没有被复制,请将复制/赋值运算符定义为私有,并查看代码是否仍然可以编译。如果是,你是安全的,否则你有问题。【参考方案3】:

我和@andrew-shepherd 在一起。由于在更改类 Trains 的初始化顺序时得到了不同的结果,因此我强烈建议您检查所有基类和派生类的“初始化列表”。

如果不允许显示具体代码sn-p,请至少确保每个类的所有数据成员都在初始化列表中,而不是在ctor中。

【讨论】:

哦,它们在构造函数中。将它们移至初始化列表会有所不同吗? 在 C++ 中,使用初始化列表总是一个更好的主意,@dominolog 给出了部分原因。由于您在派生类的不同 new() 顺序上有不同的行为,特别是在 IniConfigStore 和 Init() 周围,我们不知道它在这里做了什么,因此值得检查所有初始化进度。使用初始化列表是保证它们安全的最简单方法之一。【参考方案4】:

我只是猜测 Init 方法是虚拟的。规则没有。 1是你不应该从ctor调用虚方法,因为对象可能没有正确初始化。

问候

【讨论】:

以上是关于Std::vector 被初始化为垃圾。奇怪的行为。有啥想法吗?的主要内容,如果未能解决你的问题,请参考以下文章

新分配的 std::vector<int> 元素是不是初始化为 0?

std::vector<QString,int*> 的奇怪行为

奇怪的 std::vector::reverse_iterator 和字符串行为

C++ Vector 奇怪的行为

标准 C++ 线程 ID - 奇怪的行为

GCC的std :: sort与lambdas的不稳定行为