Project-512.exe 中的 0x00007FFECFCBB16B (ucrtbase.dll) 抛出异常:0xC0000005:访问冲突写入位置 0xFFFFFFFFF9CF4880

问题描述 投票:0回答:1

我正在尝试用 C 读取文件,但是在编写了一堆代码以分配内存之后,我在实际读取文件时遇到了问题,因为我遇到了内存访问冲突,我尝试分配比我实际上需要 char 指针,但最终我仍然遇到内存分配错误,代码当前

#include "rendering/Shader.h"
float Vertices[] = {
     0.5f,  0.5f, 0.0f,  // top right
     0.5f, -0.5f, 0.0f,  // bottom right
    -0.5f, -0.5f, 0.0f,  // bottom left
    -0.5f,  0.5f, 0.0f   // top left 
};
unsigned int indices[] = {
    0, 1, 3,   // first triangle
    1, 2, 3    // second triangle
};


unsigned int shaderProgram;
unsigned int VertexBufferObject;
unsigned int VAO;

void compileShaders()
{
    unsigned int vertexShader;
    unsigned int fragmentShader;

    // Vertex Shader
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    char* vertexShaderSource = readShader("shaders\\test\\vertex.glsl");
    printf("Vertex Shader Source:\n%s\n", vertexShaderSource);
    
    if (vertexShaderSource == NULL) {
        printf("ERROR: Failed to load vertex shader\n");
        return;
    }
    glShaderSource(vertexShader, 1, (const GLchar**)&vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    free(vertexShaderSource);  // Free the shader source after use

    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        printf("ERROR: VERTEX SHADER FAILED TO COMPILE\n%s\n", infoLog);
    }

    // Fragment Shader
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    char* fragmentShaderSource = readShader("shaders\\test\\fragment.glsl");
    printf("Fragment Shader Source:\n%s\n", fragmentShaderSource);
    if (fragmentShaderSource == NULL) {
        printf("ERROR: Failed to load fragment shader\n");
        return;
    }
    glShaderSource(fragmentShader, 1, (const GLchar**)&fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    free(fragmentShaderSource);  // Free the shader source after use

    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        printf("ERROR: FRAGMENT SHADER FAILED TO COMPILE\n%s\n", infoLog);
    }

    // Shader Program
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        printf("ERROR: SHADER PROGRAM FAILED TO LINK\n%s\n", infoLog);
    }

    // Clean up shaders (no longer needed once linked into program)
    free(vertexShaderSource);
    free(fragmentShaderSource);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}


void loadVertexData()
{
    // Generate and bind VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    // Generate and bind VBO
    glGenBuffers(1, &VertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, VertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    unsigned int EBO;
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // Set vertex attribute pointers
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Unbind VAO for now
    glBindVertexArray(0);
}

void loadShaders()
{
    glUseProgram(shaderProgram);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

static char* readShader(char path[]) {
    char cwd[1024];
    if (getcwd(cwd, sizeof(cwd)) != NULL) {
        printf("Current working dir: %s\n", cwd);
    }
    else {
        perror("getcwd() error");
    }
    int lines = 0;
    char full_path[512];
    snprintf(full_path, sizeof(full_path), "%s/%s", cwd, path);
    FILE* fpointer = fopen(full_path, "r");
    if (fpointer == NULL)
    {
        printf("ERROR: COULD NOT LOAD SHADER");
        return NULL;
    }
    int ch;
    lines++;
    while ((ch = fgetc(fpointer)) != EOF) {
        if (ch == '\n') {
            lines++;
            printf("reading line: %d \n", lines);
        }
    }
    printf("there are %d ", lines);
    printf("lines in the file %s\n", path);

    rewind(fpointer);


    fseek(fpointer, 0, SEEK_END);  // Move to the end of the file
    int fileSize = ftell(fpointer);  // Get the size of the file
    rewind(fpointer);
    printf("filesize: %d\n", fileSize);
    char* shaderCode = malloc(fileSize);
    if (shaderCode == NULL) {
        printf("Memory allocation failed\n");
        fclose(fpointer);
        return NULL;
    }
    char* str = malloc(fileSize + 1);
    if (str == NULL)
    {
        printf("Memory allocation failed\n");
        fclose(fpointer);
        return NULL;
    }

    while (fgets(str, fileSize, fpointer) != NULL) // fgets() will return NULL on EOF
    {
        printf("%s", str);
    }
    printf("%s", str);

    printf("\n");

    fclose(fpointer);

    printf("Shader loaded successfully. File size: %ld bytes\n", fileSize);
    return shaderCode;
}

错误发生在

while (fgets(str, fileSize, fpointer) != NULL) 
c file memory-management
1个回答
0
投票

代码至少有这些小问题:

不确定修复这些问题是否足够,但可以让 OP 开始。


启用所有编译器警告

这将为 OP 提供针对许多代码弱点的快速反馈。

未检查的返回值

许多可能返回失败值的函数没有被检查。

关闭1

鉴于

str
指向
fileSize + 1
字节,我希望
fgets()
能够以同样的方式读取。

// while (fgets(str, fileSize, fpointer) != NULL)
while (fgets(str, fileSize + 1, fpointer) != NULL)

不匹配说明符

使用指定的匹配说明符。

// printf("Shader loaded successfully. File size: %ld bytes\n", fileSize);
printf("Shader loaded successfully. File size: %d bytes\n", fileSize);

截断

int fileSize = ftell(fpointer);
可以截断
long
返回值。
long fileSize = ftell(fpointer);
预计。

行数:减少 1

如果最后缺少

'\n'
,则报告的计数会减少 1。

替代:

    unsigned lines = 0;
    ...
    int ch_previous = '\n';
    int ch;
    while ((ch = fgetc(fpointer)) != EOF) {
      if (ch_previous = '\n') {
        lines++;
      }
      ch_previous = ch;
    }
    printf("there are %u ", lines);
© www.soinside.com 2019 - 2024. All rights reserved.