Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;访问违规”;在运行时使用fscanf(),但在调试时不使用_C_Struct_Access Violation_Scanf - Fatal编程技术网

&引用;访问违规”;在运行时使用fscanf(),但在调试时不使用

&引用;访问违规”;在运行时使用fscanf(),但在调试时不使用,c,struct,access-violation,scanf,C,Struct,Access Violation,Scanf,有人知道这里会发生什么吗 我明白了 在这一行: fscanf(fp, " %lf %lf %lf\n", &vertices[i].x, &vertices[i].y, &vertices[i].z ); 当运行我的程序时,但当我在调试模式(VisualStudio2010)下逐步执行它时,一切都很顺利;fscanf()按预期读取文件 异常实际上是在input.c的行中抛出的: #else /* _UNICODE */ _FASSIGN( longone

有人知道这里会发生什么吗

我明白了

在这一行:

fscanf(fp, " %lf %lf %lf\n", &vertices[i].x, &vertices[i].y, &vertices[i].z );
当运行我的程序时,但当我在调试模式(VisualStudio2010)下逐步执行它时,一切都很顺利;
fscanf()
按预期读取文件

异常实际上是在
input.c
的行中抛出的:

#else  /* _UNICODE */
       _FASSIGN( longone-1, (char*)pointer , pFloatStr, (char)decimal, _loc_update.GetLocaleT());
#endif  /* _UNICODE */
如果我没弄错的话。我不知道这些关于UNICODE的评论是什么意思,这就是为什么我把它们包括在这里


附加信息 调用堆栈: 其他一些信息 该程序是关于OpenGL着色的,您在
fscanf()
调用中看到的
顶点是这些顶点的数组:

typedef struct _Vertex {
    double  x, y, z;
    int polygonsThisPartOf; // Number of polygons this vertex is a part of
    Point normal;
} Vertex;
在我的程序的第一个版本中,
顶点
是一个数组数组,一切正常;在我修改代码以将
顶点
用作上述
结构
的数组后,此异常开始出现

数组的分配
vcount
正确。

1)您的“fscanf()”语法看起来正常

2) “_UNICODE”消息(在您进入的MSVC内部)仅仅意味着您正在使用所有Win32代码的16位UNICODE版本,这需要16位UNICODE格式字符串(而不是8位ASCII格式字符串)

这是正常的,也是意料之中的。如果您在VisualStudio内部从源代码处编译所有内容,那么这应该不是问题

3) 我将集中精力确保数组元素“顶点[I]”已成功分配

建议:

在“fscanf()”处插入断点,并在调试器中调用fscanf之前查看变量

此外,您可能希望在fscanf之前添加此命令,并将断点放在该调试行:

 vertices[i].x = vertices[i].y = vertices[i].z = 0;

问题出在代码的某个地方,它甚至可能与您的fscanf调用无关,某个内存位置写入的字节数可能超过了它最可能容纳的字节数。当您在调试模式下运行时,它会分配比需要更多的内存,因此您通常不会在调试模式下看到错误,但是一个好的调试器应该告诉您何时写入超过缓冲区长度的内容。

在过去,当我遇到调试生成中没有重现的错误时,这几乎总是一个缓冲区溢出或某种指针错误

调试构建可能会以稍微不同的方式构建堆栈;堆栈上可能有额外的内容,有时当您注销缓冲区的末尾时,写入将进入调试内容,并且没有明显的错误发生。当然,这假设缓冲区是在堆栈上分配的。或者,如果缓冲区在堆中,那么调试构建可能在堆中有额外的内容(可能有额外的字符串)

因此,检查变量
i
,确保它没有从数组末尾索引。检查变量
fp
,确保它指向合理的地方;如果它是由指针算术确定的,请确保指针数学是正确的

如果它没有在调试版本中重新编译,那么您应该在发布版本中插入指令,以打印
i
的值、
fp
的值,以及其他一些内容(例如,如果
fp
是指向缓冲区内部的指针,则该缓冲区的当前地址和当前长度,因此您可以查看
fp
是否在缓冲区内)


另外,我听说过这种叫做“Heisenbug”的bug。试图调试它会改变它的行为!

你能把它归结为一个10行的程序来解决这个问题吗?告诉我们你是如何初始化
顶点的
@Bloke-换句话说(正如我在回答中暗示的那样),在开始将数据读入数组之前,我们不知道您是否已成功为数组分配了空间。我希望下面的建议能有所帮助…分配垂直数组的代码是什么样子的?对,分配。抱歉,现在开始。请检查编辑。
typedef struct _Vertex {
    double  x, y, z;
    int polygonsThisPartOf; // Number of polygons this vertex is a part of
    Point normal;
} Vertex;
    //                                              ˇ THIS is the mistake
vertices = (Vertex *) malloc(vcount * sizeof(Vertex *));
if (vertices == NULL) exit(-2);
 vertices[i].x = vertices[i].y = vertices[i].z = 0;