C语言从OBJ文件加载3个顶点值到char*数组时出现访问违规错误
解析OBJ文件时的访问违规错误排查与修复
我尝试实现一个函数读取OBJ文件,针对顶点行(以"v "开头)从第三个字符开始遍历提取坐标,但运行时出现访问违规错误。以下是我的代码:
bool LoadFromObjectFile(char* filepath) { FILE* pF; fopen_s(&pF, filepath, "r"); if (pF == NULL) return false; char buffer[128]; while (fgets(buffer, sizeof(buffer), pF) != NULL) { if (buffer[0] == 'v') { int currCoord = 0; char* vCoords[3] = { "", "", ""}; for (int i = 2; i < sizeof(buffer); i++) { if (buffer[i] == ' ') { currCoord++; continue; } strcat_s(vCoords[currCoord], sizeof(&buffer[i]), &buffer[i]); } } } printf("%s\n", buffer); fclose(pF); return true; }
错误原因分析
vCoords初始化错误:char* vCoords[3] = { "", "", ""};中每个元素指向的是只读内存中的字符串字面量,strcat_s试图修改只读内存直接触发访问违规,且字面量长度为0,没有空间容纳拼接内容。strcat_s参数逻辑错误:第二个参数传sizeof(&buffer[i])是取指针的大小(通常4/8字节),不是目标缓冲区的可用大小;第三个参数传&buffer[i]会把从i位置开始的整个剩余字符串一次性拼入,而非单个字符,逻辑完全错误。- 循环边界错误:
for (int i = 2; i < sizeof(buffer); i++)会遍历缓冲区中未初始化的垃圾数据,可能导致越界访问。 - 无边界检查:若顶点行空格数量超过2,
currCoord会变成3,访问vCoords[3]触发数组越界。
修复后的代码
#include <stdio.h> #include <string.h> #include <stdbool.h> bool LoadFromObjectFile(char* filepath) { FILE* pF; if (fopen_s(&pF, filepath, "r") != 0 || pF == NULL) { return false; } char buffer[128]; while (fgets(buffer, sizeof(buffer), pF) != NULL) { // 精准匹配顶点行,避免误判vn、vt等行 if (buffer[0] == 'v' && buffer[1] == ' ') { // 给每个坐标分配可写缓冲区,预留足够空间 char vCoords[3][32] = {0}; int currCoord = 0; int charIndex = 0; // 仅遍历有效字符串内容 for (int i = 2; buffer[i] != '\0'; i++) { if (buffer[i] == ' ') { // 跳过连续空格 if (charIndex == 0) continue; // 切换坐标前检查边界 if (currCoord < 2) { currCoord++; charIndex = 0; } continue; } // 防止缓冲区溢出 if (charIndex < 31) { vCoords[currCoord][charIndex++] = buffer[i]; } } // 打印测试提取结果 printf("顶点坐标:x=%s, y=%s, z=%s\n", vCoords[0], vCoords[1], vCoords[2]); } } fclose(pF); return true; }
关键修复点
- 将
vCoords改为二维字符数组,提供可写内存空间,避免修改只读字面量。 - 逐个字符写入目标缓冲区,替代错误的
strcat_s调用,同时做溢出检查。 - 循环终止条件改为
buffer[i] != '\0',只处理有效字符串内容。 - 增加连续空格跳过逻辑和
currCoord边界检查,防止数组越界。 - 完善顶点行判断条件,避免误处理法向量、纹理坐标等行。
内容的提问来源于stack exchange,提问作者Slykapar
相关产品推荐
相关产品推荐

