for循环中未处理的异常

Posted

技术标签:

【中文标题】for循环中未处理的异常【英文标题】:Unhandled exception in for loop 【发布时间】:2018-09-22 02:24:02 【问题描述】:

我正在尝试为我的 OpenGL 项目创建两个纹理。最初我分别创建纹理,这工作得非常好。不再重复我自己,我决定尝试将它们作为一个数组并使用 for 循环执行两次。

unsigned int textures[2];
int width, height, nrChannels;
unsigned char *data = stbi_load("C:\\Users\\A\\Desktop\\wall.jpg", &width, &height, &nrChannels, 0);
glGenTextures(2, textures);
for (int i = 0; i < 2; i++)

    glBindTexture(GL_TEXTURE_2D, (i == 0) ? textures[0] : textures[1]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    if (data)
    
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, (i == 0) ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
        if (i == 1)
        data = stbi_load("C:\\Users\\A\\Desktop\\awesomeface.png", &width, &height, &nrChannels, 0);
    
    else
    
        std::cout << "Failed to load texture!" << std::endl;
    

在第 13 行 (glTexImage2D),我收到以下未处理的异常:

LearnOpenGL.exe 中 0x03EE8893 (ig9icd32.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0x00942000。

基本上我有 3 个问题,是什么导致了这个错误?我该如何解决?无论如何,这是一种不好的方式吗?

编辑:

这是我的旧代码,运行良好:

unsigned int texture1, texture2;
// texture 1
// ---------
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// load image, create texture and generate mipmaps
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
unsigned char *data = stbi_load("C:\\Users\\A\\Desktop\\wall.jpg", &width, &height, &nrChannels, 0);
if (data)

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);

else

    std::cout << "Failed to load texture" << std::endl;

stbi_image_free(data);
// texture 2
// ---------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// load image, create texture and generate mipmaps
data = stbi_load("C:\\Users\\A\\Desktop\\awesomeface.png", &width, &height, &nrChannels, 0);
if (data)

    // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);

else

    std::cout << "Failed to load texture" << std::endl;

stbi_image_free(data);

【问题讨论】:

你读了第二张图片两次(“awesomeface.png”),你从来没有通过stbi_image_free释放任何内存。 不是问题.. 当然不是“the”问题,而是另一个问题。 我觉得你应该在glTexImage2D之后打电话给stbi_image_free(data); 【参考方案1】:

请阅读您正在使用的库的手册。

Loading images with stb 写道:

stbi_load() 的第五个参数指定每个像素要使用的 8 位分量的数量。可以设置为以下四个选项之一:

STBI_grey = 1

STBI_grey_alpha = 2

STBI_rgb = 3

STBI_rgb_alpha = 4

如果您将0 作为第五个参数传递,stbi_load() 将使用您的nrChannels,它在您的代码中未初始化,因此会导致未定义的行为。

【讨论】:

嘿剑鱼!感谢您花时间看我的帖子。话虽如此,答案不完整。它在进入循环之前不会导致任何未定义的行为。那么这里发生了什么? 我还可以补充一点,据我所知,更改这些值并不能解决问题。 很抱歉,如果更改不能解决您的问题,但读取未初始化的整数绝对是未定义的行为。 当然是这样。我不知道 stbi_load 函数是如何工作的,但我显然对它来说不是问题。至少在我重做之前没有。 github.com/nothings/stb/blob/master/stb_image.h: "如果 desired_channels 不为零,则组件数 N 为 'desired_channels',否则为 *channels_in_file。"因此,如果您将0 作为第五个参数传递并且不初始化您作为第四个参数传递的内容,则会出现问题。

以上是关于for循环中未处理的异常的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 在 for 循环中执行即时异常处理

Sonarqube 抱怨 for 循环中未使用的变量 [重复]

异常处理并在 python 中继续 for 循环

减少计数值以重复循环循环不起作用。 python中的for循环有一个异常处理程序,它有一个continue语句

Java - 在 for 循环中使用“继续”时出现未处理的异常错误?

ECMAscript之if..else语句,for循环,while循环,switch,case语句,异常处理