【问题标题】:C++ object reference corruption [closed]C ++对象引用损坏[关闭]
【发布时间】:2013-02-22 21:22:06
【问题描述】:

创建对对象的引用会导致该引用被破坏。这绝对是奇怪的,因为它似乎是简单的 C++ 功能。另一个奇怪的事情是,问题似乎已经出现而没有更改任何相关代码(我知道)。如果我不得不猜测,我会说这与所涉及的 DirectX 代码有关。

代码如下:

// the header file of the class of the problem object
#pragma once

#include<vector>
#include<Windows.h>
#include<xnamath.h>
#include<string>
using namespace std;

#define float2 XMFLOAT2
#define float4 XMFLOAT4

namespace DXLib
{
    struct Sprite
    {
        char* imagename;
        float2 pos;
        float rot;
        float2 scale;
        float4 rgba;
    };

    struct Rect
    {
        float2 pos;
        float2 size;
        float4 color;
    };

    struct Text
    {
        std::string string;
        float2 pos;
    };

    class D3DDraw
    {
    public:
        D3DDraw(int maxdepth = 0);
        ~D3DDraw(void);
        void DrawSprite(char* imagename, float2 pos, int depth = 0, float rot = 0.0f, XMFLOAT2 scale = XMFLOAT2(1, 1), float4 rgba = float4(1, 1, 1, 1));
        //void DrawRect(float2 pos, float2 size, float4 color);
        void DrawDXText(std::string string, float2 pos);
        void Clear(void);

    public:
        std::vector<vector<Sprite>> depths_;
        std::vector<Text> texts_;
        int maxdepth_;  // set on initialize, do not change
        float2 spriteoffset_;
    };
}


// the header file for the base class for the class in which the problem occurs
#pragma once
#include <windows.h>
#include"D3DCore.h"
#include"D3DRender.h"
#include"D3DDraw.h"
#include"DXInput.h"
#include<cassert>
using namespace DXLib;


const UINT uWindowSizeX = 1000;
const UINT uWindowSizeY = 800;


class Application
{
public:
    Application();
    ~Application();
    HRESULT Run();

protected:
    virtual void Update(void);

private:
    static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

protected:
    D3DDraw m_cDraw;
    DXInput m_cInput;

private:
    HWND m_hWnd;
    D3DCore m_cCore;
    D3DRender m_cRender;
};


// the class header file
#pragma once
#include"stdafx.h"
#include"VGraphics.h"
#include"EntityPool.h"
#include"VUI.h"
#include"Manager.h"

class VApp : public Application
{
public:
    VApp(void);
    ~VApp(void);
    virtual void Update(void) override;

private:
    void Log(double dTime);  // prints log info to console every nth frame

private:
    int m_iTime;
    VGraphics m_cGraphics;
    EntityPool m_cPool;
    VUI m_cVUI;
    Manager m_cManager;
};


// the function in which the problem occurs
void VApp::Update(void)
{
    double dTime = (GetTickCount() - m_iTime) / 1000.0;

    D3DDraw& rcDraw = m_cDraw; // that object is initialized and just fine
    // that reference now points to an uninitialized object
    m_cVUI.Tick(m_cInput, m_cDraw, m_cPool, m_cManager);

    m_cManager.Tick();

    m_cGraphics.Draw(m_cVUI.GetView(), m_cPool, m_cDraw);

    Log(dTime);

    m_iTime = GetTickCount();
    Sleep(15);
}

【问题讨论】:

  • 这段代码没有意义,可能与问题无关。做一个Short, Self Contained, Compilable, Example
  • 是的,我知道,还有什么奇怪的是它成为了一个最近的问题,没有对相关代码进行任何更改(据我所知)
  • 不,我不是说你的问题没有意义,我的意思是你在这个页面上放的词没有意义。请制作 SSCCE,并编辑问题以使其更清晰,然后我们将能够为您提供帮助。
  • 一个想法:创建一个需要引用的变量的堆栈本地副本,看看是否发生了同样的事情(意思是在堆栈上创建一个 D3DDraw& 以传递给 Tick)。 *this 指针是否会超出范围? Tick 是否尝试存储 ref 对象的副本?
  • 这是一个绝妙的建议 silverjam!我试图在调用函数中创建对同一对象的引用,但发生了同样的问题

标签: c++ object reference


【解决方案1】:

我不知道为什么,但在这里更改访问说明符:

protected:
    D3DDraw m_cDraw;
    DXInput m_cInput;

致 public 解决了这个问题,这是一个 hack,但我可以接受 :D

感谢您的帮助

【讨论】:

    【解决方案2】:

    嗯,这是我对 SSCCE 的尝试,但我无法让它失败(可能与通过 pointer to the wrong kind of object 访问受保护的成员有关):

    class Thing 
    { 
    public:
        int value;
        Thing() { value = 42; }
        ~Thing() { };
    };
    
    class Foo
    {
    public:
        Foo() { }
        ~Foo() { }
    
    public:
        void CallMethod()
        {
            Method();
        }
    
    protected:
        virtual void Method()
        {
        }
    
        Thing m_x;
    };
    
    class Bar : public Foo
    {
    public:
        Bar() { }
        ~Bar() { }
    
        virtual void Method() override
        {
            Thing& x = m_x;
            printf("%d\n", x.value);
        }
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        Foo f;
        Foo& rf = f;
    
        printf("%p\n", &rf);
    
        Bar bar;
    
        Foo& rfoo = bar;
        rfoo.CallMethod();
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-07
      • 2012-01-15
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 2016-01-06
      • 2020-04-11
      • 1970-01-01
      相关资源
      最近更新 更多