在Windows窗体中使用向量时出现访问冲突异常

时间:2016-03-01 02:43:50

标签: .net winforms visual-c++

更新
在我创建的调试解决方案中,我将所有类更改为托管类,以查看它是否发生了任何变化。当我这样做时,错误更改为NullReferneceException,这让我觉得我没有在调用它们之前初始化我的类。

更新2
在进行了一些挖掘之后,在我看来,我的类正在被初始化,构建,然后在构造表单时被丢弃。但是这没有意义,因为在问题发生之前我能够一直访问CountryList对象。但总之,我认为这个问题与我的表格本身有关。

背景

我正在创建一个项目,在其中我使用相当简单的窗体显示一堆信息。显示的信息包含存储在表单后台创建的自定义类中的整数,并显示在表单上的标签中。我的一个自定义类CountryList有一个84个指向Country s的向量,我的类包含我想要显示的数据。

我的CountryList类在名为Gamestate的第三个类中初始化,该类负责处理程序的所有后端逻辑。这是我唯一一个直接与我的表格互动的课程。

问题

当我尝试在运行时从我的Country访问CountryList以动态更改表单上显示的内容时,我收到以下错误:

  

无法访问AccessViolationException
  尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

该错误打开vector类的文件,特别是在size()函数触发。调用堆栈如下所示:

  • Foo.exe!std :: vector> :: size()第1179行
  • Foo.exe!std :: vector> :: at(unsigned __int64 _Pos)Line 1206 + 0x9 bytes
  • Foo.exe!CountryList :: get_country(int x)第20行+ 0xf字节
  • Foo.exe!Foo :: MyForm :: button1_Click(System :: Object ^ sender,System :: EventArgs ^ e)第78行+ 0x27字节
  • [外部代码]
  • Foo.exe!Main(array ^ args)第15行+ 0x9字节

代码

以下是调试版本的代码,我将其作为最小,完整和可验证的示例,同时尽可能保持与原始项目的接近。

Country.h

#pragma once
class Country
{
public:
    Country(int x);
    int get_bar();
private:
    int bar;
}; 

Country.cpp

#include "Country.h"

Country::Country(int x)
{
    bar = x;
}

int Country::get_bar()
{
    return this->bar;
}

CountryList.h

#pragma once
#include <vector>
#include "Country.h"

class CountryList
{
public:
    CountryList();
    Country* get_country(int x);
private:
    std::vector<Country> countries;
};  

CountryList.cpp

#include "CountryList.h"

CountryList::CountryList()
{
    countries.reserve(3);

    Country a(1);
    this->countries.push_back(a);

    Country b(2);
    this->countries.push_back(b);

    Country c(3);
    this->countries.push_back(c);
}

Country* CountryList::get_country(int x)
{
    return &this->countries.at(x);
}   

Gamestate.h

#pragma once
#include "CountryList.h"

class Gamestate
{
public:
    Gamestate();
    CountryList* countryLst;
};

Gamestate.cpp

#include "Gamestate.h"

Gamestate::Gamestate()
{
    CountryList* countryLst = new CountryList();
}

MyForm.h

#pragma once
#include "Gamestate.h"

namespace Foo {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    public ref class MyForm : public System::Windows::Forms::Form
    {
    public:
        MyForm(void)
        {
            InitializeComponent();
        }

    protected:
        ~MyForm()
        {
            if (components)
            {
                delete components;
            }
        }
    private: Gamestate* game = new Gamestate();
    private: System::Windows::Forms::Label^  label1;
    private: System::Windows::Forms::Button^  button1;
    protected:

    private:
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        void InitializeComponent(void)
        {
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->SuspendLayout();
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(39, 39);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(35, 13);
            this->label1->TabIndex = 0;
            this->label1->Text = L"label";
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(114, 34);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(75, 23);
            this->button1->TabIndex = 1;
            this->button1->Text = L"button1";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this, &MyForm::button1_Click);
            // 
            // MyForm
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(284, 74);
            this->Controls->Add(this->button1);
            this->Controls->Add(this->label1);
            this->Name = L"MyForm";
            this->Text = L"MyForm";
            this->ResumeLayout(false);
            this->PerformLayout();

        }
#pragma endregion

//problem occurs when this event is triggered
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        this->button1->Text = System::Convert::ToString(this->game->countryLst->get_country(1)->get_bar());
    }
    };
}  

MyForm.cpp

#include "MyForm.h"

using namespace System;
using namespace System::Windows::Forms;


[STAThread]
void Main(array<String^>^ args)
{
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);

    Foo::MyForm form;
    Application::Run(%form);
}   

您可以给予的任何帮助将不胜感激。

0 个答案:

没有答案