[英]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.