簡體   English   中英

尋找我在這里遇到訪問沖突的原因

[英]Looking for insight into why I'm getting an access violation here

我正在嘗試創建一個點列表,其 z 值將被灰度圖像的 alpha 值修改。 由於點被分配到一個列表,我不斷收到訪問沖突。 我在調試過程中注意到 alpha 數組的大小在 for 循環中間突然改變,以及我的寬度和高度值。 我是 C++ 的新手,所以我想這是一個明顯的錯誤。 這是相關的代碼:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

// image processing libs
#include "vendors/stb_image/stb_image.h"
#include "vendors/stb_image/stb_image_write.h"

#include "Image.h"
#include "Renderer.h"
#include "VertexBufferLayout.h"

// signed normalization function for scaling input value with a known input range to an output range
float snorm(float value, float in_Min, float in_Max) 
{
    float out_Value = ( ((1.0f - 1.0f) * ((value - in_Min) / (in_Max - in_Min))) + -1.0f );
    return out_Value;
}

int main(void) 
{   
    // CONSTANTS
    const int SCREEN_WIDTH = 2000;
    const int SCREEN_HEIGHT = 2000;
    // glsl version
    const char* glsl_version = "#version 330";

    Image image("res/images/drama_mask_white.jpg");
    // loads an image to greyscale (normal) and returns the path to that normal
    std::string normal_Path = image.ImgToGrayScale("gray_mask");
    image.GetAlphas(normal_Path);
    image.setMinMaxAlphas();
    
    const std::vector<float> * lcl_Alphas = &image.alpha_Map;
    const int lcl_Width = image.img_Width;
    const int lcl_Height = image.img_Height;

    const float x_Increment = 2.0f / lcl_Width; 
    const float y_Increment = 2.0f / lcl_Height;


    float positions[] = { 0 };
    //unsigned int indices[] = { 0 };
    unsigned int row = 0;
    unsigned int col = 0;
    unsigned int num_Rows = 0;
    unsigned int num_Cols = 0;
    unsigned int num_Verteces = 0; 
    unsigned int pos_Count = 0; 

    for (int i = 0; (unsigned)i < image.alpha_Map.size(); i++)  
    {
        // checks for the end of the row
        if (i > 0 && (i % (image.img_Width - 1)) == 0)
        {
            row++; // if we've reached the end of a row, increment row index
            num_Cols = col;
            col = 0; // reset column index at end of each row
        }


        // assign position values starting from bottom left
        // X
        positions[pos_Count] = -1.0f + (col * x_Increment);
        // Y
        positions[pos_Count + 1] = -1.0f + (row * y_Increment);
        // Z
        // ERROR OCCURS HERE
        positions[pos_Count + 2] = snorm(image.alpha_Map[i], image.min_Alpha, image.max_Alpha);
        pos_Count += 3;
        // indices
        //indices[i] = i;

        col++; // increment column index 
        num_Verteces++;
    }

    std::cout << "Num Verteces: " << num_Verteces << std::endl;
    std::cout << "Num Positions: " << pos_Count << std::endl;

    num_Rows = row; 

    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    // create window and context with core profile
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    glfwSwapInterval(1);

    // checks if GLEW intializes correctly
    if (glewInit() != GLEW_OK)
        std::cout << "ERROR!" << std::endl;

    std::cout << glGetString(GL_VERSION) << std::endl;

    // enable blending
    GLCall(glEnable(GL_BLEND));
    // get source alpha, subtract from one to blend alpha at destination  
    GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));

    // init renderer object
    Renderer renderer;

    GLfloat test_Vertex[] = { SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0.0f };

    while (!glfwWindowShouldClose(window)) {

        GLCall(glClearColor(0.0, 0.0, 0.0, 1.0));
        renderer.Clear();

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, test_Vertex);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDrawArrays(GL_POINTS, 0, 1);

        // Swap front and back buffers
        glfwSwapBuffers(window);

        // Poll for, and process events
        glfwPollEvents();
    }
    glfwTerminate();
 }

@Rabbid76 和 @Peter 在這里有正確的想法......我需要使用 std::vector 因為我只用元素初始化數組,但在 for 循環期間填充它。 一旦我轉換為 std::vector 它就可以正常工作。 現在要讓這個東西真正畫點......

我看到你是一個新的貢獻者。 我認為將來您可以在“最小化”示例代碼方面做得更好。 總體思路:嘗試刪除行以使用盡可能少的代碼發生錯誤,也許您會發現一行有所不同。 這也有助於您在詢問他人之前發現錯誤。

我認為這里的一個大問題可能是您的positions數組的大小始終為 1。這使得在修復此問題之前很難找出其余代碼中的任何其他問題。

使用float positions[] = { 0 }; 意味着編譯器只會為位置數組保留足夠的空間來包含 1 個浮點值。 因此寫入positions[0] = 42是有效的,但寫入positions[1] = 42可能已經很糟糕了。 也許您很幸運,您的程序會立即崩潰。 如果你不走運,你的程序將寫入數組末尾的內存,如果你特別不走運,這個內存包含一些重要的東西。 它可能包含諸如 alpha 向量的大小或內存中的任何其他數據。 因此,它導致的錯誤可能變得非常不可預測。

    int main() {
      char greeting[] = "Hello World!\n";
      float positions[] = { 0 };
      positions[0] = 42; // GOOD inside array bounds
      positions[4] = 42; // BAD outside array bounds destroying other data
      std::cout << greeting;
    }

這是一個示例,我通過寫出數組的邊界來故意破壞 hello-world 問候語。 如果您提供有關您使用的 IDE 或編譯器的信息,人們能夠告訴您如何啟用或查看此類錯誤的警告。 例如GCC 的 -Wall或 -Warray-bounds。 或者您可以通過添加“越界警告”來自行搜索。

示例的輸出

    > clang++-7 -pthread -std=c++17 -o main main.cpp
    main.cpp:7:3: warning: array index 4 is past the end of the array
          (which contains 1 element) [-Warray-bounds]
      positions[4] = 42; // BAD outside array bounds destroying other data
      ^         ~
    main.cpp:5:3: note: array 'positions' declared here
      float positions[] = { 0 };
      ^
    1 warning generated.
    > ./main
    Hello Worl 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM