我正在尝试用 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)
代码至少有这些小问题:
不确定修复这些问题是否足够,但可以让 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);