简体   繁体   English

运行时检查失败#2-变量'indices'周围的堆栈已损坏

[英]Run-Time Check Failure #2 - Stack around the variable 'indices' was corrupted

well I think I know what the problem is. 好吧,我想我知道问题出在哪里。 I am just having a hard time debugging it. 我很难调试它。 I am working with the directx api and I am trying to generate a plane along the x and z axis according to a book I have. 我正在使用DirectIX api,并且尝试根据我拥有的书沿x和z轴生成平面。 The problem is when I am creating my indices. 问题是当我创建索引时。 I think I am setting values out of the bounds of the indices array. 我想我正在设置值超出索引数组的范围。 I am just having a hard time figuring out what I did wrong. 我很难弄清楚我做错了什么。 I am unfamiliar with the this method of generating a plane. 我不熟悉这种生成平面的方法。 so its a little difficult for me. 所以对我来说有点困难。 below is my code. 下面是我的代码。 Take emphasis on the indices loop. 强调索引循环。

[edit] Ive been reviewing it. [编辑]我一直在审查它。 This is how the indices works 索引就是这样工作的

 int curVertex = x + (z * NUM_VERTSX);

This always gets the beginning vertices. 这总是得到起始顶点。 so say we have 17 vertices on the x axis and 17 vertices on the z axis and we are on the first loop of the x and z axis 假设我们在x轴上有17个顶点,在z轴上有17个顶点,并且在x和z轴的第一个循环中

curVertx = 0 + (0 * 17) curVertx = 0 + 0 = 0 curVertx = 0 +(0 * 17)curVertx = 0 + 0 = 0

say we are on the first loop of the z axis and second loop of the x axis 说我们在z轴的第一个循环和x轴的第二个循环上

curVertx = 1 + (0 * 17) curVertx = 1+ 0 = 1 curVertx = 1 +(0 * 17)curVertx = 1+ 0 = 1

indices[curIndex] = curVertex;
            indices[curIndex + 1] = curVertex + NUM_VERTSX;
            indices[curIndex + 2] = curVertex + 1;

            indices[curIndex + 3] = curVertex + 1;
            indices[curIndex + 4] = curVertex + NUM_VERTSX;
            indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;

if we are on the first 如果我们在第一个

loop indices[curIndex] = curVertex;

this equals the first vertex = 0. 这等于第一个顶点= 0。

indices[curIndex + 1] = curVertex + NUM_VERTSX;

this equals the second row vertices (its always the vertices below the starting vertices 这等于第二行顶点(它始终是起始顶点以下的顶点

xxxx XXXX

[x] xxx [x] xxx

#include "MyGame.h"
//#include "CubeVector.h"
/* This code sets a projection and shows a turning cube. What has been added is the project, rotation and
a rasterizer to change the rasterization of the cube. The issue that was going on was something with the effect file
which was causing the vertices not to be rendered correctly.*/
typedef struct 
{
    ID3D10Effect* pEffect;
    ID3D10EffectTechnique* pTechnique;

    //vertex information
    ID3D10Buffer* pVertexBuffer;
    ID3D10Buffer* pIndicesBuffer;
    ID3D10InputLayout* pVertexLayout;

    UINT numVertices;
    UINT numIndices;
}ModelObject;

ModelObject modelObject;
// World Matrix
D3DXMATRIX                  WorldMatrix;
// View Matrix
D3DXMATRIX                  ViewMatrix;
// Projection Matrix
D3DXMATRIX                  ProjectionMatrix;
ID3D10EffectMatrixVariable* pProjectionMatrixVariable = NULL;

//grid information
#define NUM_COLS 16
#define NUM_ROWS 16

#define CELL_WIDTH 32
#define CELL_HEIGHT 32

#define NUM_VERTSX (NUM_COLS + 1)
#define NUM_VERTSY (NUM_ROWS + 1)




bool MyGame::InitDirect3D()
{
    if(!DX3dApp::InitDirect3D())
    {
        return false;
    }

    D3D10_RASTERIZER_DESC rastDesc;
    rastDesc.FillMode = D3D10_FILL_WIREFRAME;
    rastDesc.CullMode = D3D10_CULL_FRONT;
    rastDesc.FrontCounterClockwise = true;
    rastDesc.DepthBias = false;
    rastDesc.DepthBiasClamp = 0;
    rastDesc.SlopeScaledDepthBias = 0;
    rastDesc.DepthClipEnable = false;
    rastDesc.ScissorEnable = false;
    rastDesc.MultisampleEnable = false;
    rastDesc.AntialiasedLineEnable = false;

    ID3D10RasterizerState *g_pRasterizerState;
    mpD3DDevice->CreateRasterizerState(&rastDesc, &g_pRasterizerState);
    mpD3DDevice->RSSetState(g_pRasterizerState);

    // Set up the World Matrix
    D3DXMatrixIdentity(&WorldMatrix);
    D3DXMatrixLookAtLH(&ViewMatrix, new D3DXVECTOR3(0.0f, 10.0f, -20.0f), new D3DXVECTOR3(0.0f, 0.0f, 0.0f), new D3DXVECTOR3(0.0f, 1.0f, 0.0f));
    // Set up the projection matrix
    D3DXMatrixPerspectiveFovLH(&ProjectionMatrix, (float)D3DX_PI * 0.5f, (float)mWidth/(float)mHeight, 0.1f, 100.0f);

    if(!CreateObject())
    {
        return false;
    }

    return true;
}

//These are actions that take place after the clearing of the buffer and before the present
void MyGame::GameDraw()
{

    static float rotationAngle = 0.0f;

    // create the rotation matrix using the rotation angle
    D3DXMatrixRotationY(&WorldMatrix, rotationAngle);
    rotationAngle += (float)D3DX_PI * 0.0f;

    // Set the input layout
    mpD3DDevice->IASetInputLayout(modelObject.pVertexLayout);

    // Set vertex buffer
    UINT stride = sizeof(VertexPos);
    UINT offset = 0;
    mpD3DDevice->IASetVertexBuffers(0, 1, &modelObject.pVertexBuffer, &stride, &offset);
    mpD3DDevice->IASetIndexBuffer(modelObject.pIndicesBuffer, DXGI_FORMAT_R32_UINT, 0);

    // Set primitive topology
    mpD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // Combine and send the final matrix to the shader
    D3DXMATRIX finalMatrix = (WorldMatrix * ViewMatrix * ProjectionMatrix);
    pProjectionMatrixVariable->SetMatrix((float*)&finalMatrix);


    // make sure modelObject is valid


    // Render a model object
    D3D10_TECHNIQUE_DESC techniqueDescription;
    modelObject.pTechnique->GetDesc(&techniqueDescription);

    // Loop through the technique passes
    for(UINT p=0; p < techniqueDescription.Passes; ++p)
    {
        modelObject.pTechnique->GetPassByIndex(p)->Apply(0);

        // draw the cube using all 36 vertices and 12 triangles
        mpD3DDevice->DrawIndexed(modelObject.numIndices,0,0);
    }
}

//Render actually incapsulates Gamedraw, so you can call data before you actually clear the buffer or after you 
//present data
void MyGame::Render()
{
    DX3dApp::Render();
}

bool MyGame::CreateObject()
{
    VertexPos vertices[NUM_VERTSX * NUM_VERTSY];
    for(int z=0; z < NUM_VERTSY; ++z)
    {
        for(int x = 0; x < NUM_VERTSX; ++x)
        {
            vertices[x + z * NUM_VERTSX].pos.x = (float)x * CELL_WIDTH;
            vertices[x + z * NUM_VERTSX].pos.z = (float)z * CELL_HEIGHT;

            vertices[x + z * NUM_VERTSX].pos.y = 0.0f;

            vertices[x + z * NUM_VERTSX].color = D3DXVECTOR4(1.0, 0.0f, 0.0f, 0.0f);
        }
    }

    DWORD indices[NUM_VERTSX * NUM_VERTSY];
    int curIndex = 0;

    for(int z=0; z < NUM_ROWS; ++z)
    {
        for(int x = 0; x < NUM_COLS; ++x)
        {
            int curVertex = x + (z * NUM_VERTSX);
            indices[curIndex] = curVertex;
            indices[curIndex + 1] = curVertex + NUM_VERTSX;
            indices[curIndex + 2] = curVertex + 1;

            indices[curIndex + 3] = curVertex + 1;
            indices[curIndex + 4] = curVertex + NUM_VERTSX;
            indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;

            curIndex += 6;
        }
    }



    //Create Layout
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT, 0 , 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
        {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 12, D3D10_INPUT_PER_VERTEX_DATA, 0}
    };

    UINT numElements = (sizeof(layout)/sizeof(layout[0]));
    modelObject.numVertices = sizeof(vertices)/sizeof(VertexPos);

    //Create buffer desc
    D3D10_BUFFER_DESC bufferDesc;
    bufferDesc.Usage = D3D10_USAGE_DEFAULT;
    bufferDesc.ByteWidth = sizeof(VertexPos) * modelObject.numVertices;
    bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    bufferDesc.MiscFlags = 0;

    D3D10_SUBRESOURCE_DATA initData;
    initData.pSysMem = vertices;
    //Create the buffer

    HRESULT hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pVertexBuffer);
    if(FAILED(hr))
        return false;

    modelObject.numIndices = sizeof(indices)/sizeof(DWORD);

    bufferDesc.ByteWidth = sizeof(DWORD) * modelObject.numIndices;
    bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;

    initData.pSysMem = indices;

    hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pIndicesBuffer);
    if(FAILED(hr))
        return false;


    /////////////////////////////////////////////////////////////////////////////
    //Set up fx files
    LPCWSTR effectFilename = L"effect.fx";
    modelObject.pEffect = NULL;

     hr = D3DX10CreateEffectFromFile(effectFilename,
        NULL,
        NULL,
        "fx_4_0",
        D3D10_SHADER_ENABLE_STRICTNESS,
        0,
        mpD3DDevice,
        NULL,
        NULL,
        &modelObject.pEffect,
        NULL,
        NULL);

    if(FAILED(hr))
        return false;

    pProjectionMatrixVariable = modelObject.pEffect->GetVariableByName("Projection")->AsMatrix();
    //Dont sweat the technique. Get it!
    LPCSTR effectTechniqueName = "Render";

    modelObject.pTechnique = modelObject.pEffect->GetTechniqueByName(effectTechniqueName);
    if(modelObject.pTechnique == NULL)
        return false;


    //Create Vertex layout
    D3D10_PASS_DESC passDesc;
    modelObject.pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);

    hr = mpD3DDevice->CreateInputLayout(layout, numElements,
        passDesc.pIAInputSignature,
        passDesc.IAInputSignatureSize,
        &modelObject.pVertexLayout);
    if(FAILED(hr))
        return false;

    return true;
}

Your indices array contains 6 entries per 'cell' (since you're drawing two triangles for each), therefore it should be declared as 您的indices数组每个“单元格”包含6个条目(因为您要为每个单元格绘制两个三角形),因此应将其声明为

DWORD indices[NUM_ROWS * NUM_COLS * 6]

The error you get tells you, that you write outside the boundaries of indices , this is usually either a hint towards a wrong declaration (or a wrong index calculation). 您得到的错误告诉您,您在indices的边界之外书写,这通常是对错误声明(或错误的索引计算)的提示。

Now let us take the code snippet in question (probable root cause) 现在,让我们考虑有问题的代码片段(可能的根本原因)

Code

 DWORD indices[NUM_VERTSX * NUM_VERTSY];
int curIndex = 0;

for(int z=0; z < NUM_ROWS; ++z)
{
    for(int x = 0; x < NUM_COLS; ++x)
    {
        int curVertex = x + (z * NUM_VERTSX);
        indices[curIndex] = curVertex;
        indices[curIndex + 1] = curVertex + NUM_VERTSX;
        indices[curIndex + 2] = curVertex + 1;

        indices[curIndex + 3] = curVertex + 1;
        indices[curIndex + 4] = curVertex + NUM_VERTSX;
        indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;

        curIndex += 6;
    }
}

Analysis 分析

  1. Here indices have max number of 'cells' = NUM_VERTX * NUM_VERTSY = (16 + 1) * (16+1) = 289. So there are 0...288 'cells'. 在这里,索引具有“单元格”的最大数量= NUM​​_VERTX * NUM_VERTSY =(16 + 1)*(16 + 1)=289。因此,有0 ... 288个“单元格”。 During the boundary condition - there value of z = 15, x = 15. So curIndex would be 15 * 15 * 6 = 1350. This far exceeds allocated cells. 在边界条件下-z = 15,x =15。因此,curIndex为15 * 15 * 6 =1350。这远远超出了分配的像元。

Suggestion 建议

  1. Since three values determine the size of the target array, all three must be part of the allocation of the array. 由于三个值决定了目标数组的大小,因此所有三个值必须是数组分配的一部分。 so if you use DWORD indices[NUM_VERTSX * NUM_VERTSY * UNIT_BLOCK], where UNIT_BLOCK = 6, it should work fine. 因此,如果您使用DWORD索引[NUM_VERTSX * NUM_VERTSY * UNIT_BLOCK],其中UNIT_BLOCK = 6,它应该可以正常工作。

  2. Also instead of embedding magic number inside the code, you can use a const variable - it would help a great deal later (if you want to change the value of the index). 另外,也可以使用const变量,而不是在代码中嵌入幻数-以后将有很大帮助(如果要更改索引的值)。

HTH HTH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 运行时检查失败 #2 - 变量“IDNumber”周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 'IDNumber' was corrupted 运行时检查失败#2-变量&#39;result&#39;周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 'result' was corrupted 运行时检查失败#2-变量&#39;numberchoices&#39;周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 'numberchoices' was corrupted 运行时检查失败#2-变量&#39;ex&#39;周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 'ex' was corrupted 运行时检查失败#2-变量&#39;NearID&#39;周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 'NearID' was corrupted 运行时检查失败-变量周围的堆栈已损坏 - Run-Time Check Failure - Stack around variable was corrupted 运行时检查失败#2-变量&#39;s&#39;周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 's' was corrupted 运行时检查失败#2 - 变量&#39;B&#39;周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 'B' was corrupted 运行时检查失败#2-变量周围的堆栈-已损坏 - Run-Time Check Failure #2 - Stack around the variable — was corrupted 运行时检查失败 #2 - 变量“newRow”周围的堆栈已损坏 - Run-Time Check Failure #2 - Stack around the variable 'newRow' was corrupted
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM