今天我遇到了与gcc的奇怪遭遇.考虑以下代码:
float len[ELEM+1];
len[1]=1.0; len[2]=2.0; len[3]=3.0; //length
nod[1][1] = 1;
nod[1][2] = 2;
nod[2][1] = 2;
nod[2][2] = 3;
nod[3][1] = 3;
nod[3][2] = 4; //CONNECTIVITY
for(i=1;i<nnod;i++)
for(j=1;j<nfree;j++)
/* blah blah.........*/
Run Code Online (Sandbox Code Playgroud)
一个变化:
float len[ELEM+1];
len[1]=1.0; len[2]=2.0; len[3]=3.0; //length
nod[1][1] = 1;
nod[1][2] = 2;
nod[2][1] = 2;
nod[2][2] = 3;
nod[3][1] = 3;
nod[3][2] = 4; //CONNECTIVITY
Run Code Online (Sandbox Code Playgroud)
LEN [1] = 1.0; LEN [2] = 2.0;
for(i=1;i<=nnod;i++)
for(j=1;j<=nfree;j++)
/* blah blah.........*/
Run Code Online (Sandbox Code Playgroud)
唯一的区别是以粗体突出显示.问题是:当稍后打印长度时,第一个代码打印len [1]和len [2](并在表达式中使用它们)为0.0000,而第二个代码打印并使用这些变量的正确值.
怎么了?我完全糊涂了.: -
注意:len不会在其他地方修改.
您需要向我们展示其定义nod.你有一个很好的机会(基于你在1,而不是0开始数组的事实),你正在覆盖内存.
例如,如果将nod定义为:
int nod[3][2];
Run Code Online (Sandbox Code Playgroud)
可能的数组下标是0-2和0-1,而不是 1-3和1-2:
nod[0][0] nod[1][0] nod[2][0]
nod[0][1] nod[1][1] nod[2][1]
Run Code Online (Sandbox Code Playgroud)
如果是这种情况,你的记忆几乎肯定会被覆盖,在这种情况下所有的赌注都会被取消.你可能会破坏任何其他数据.
如果len紧跟在内存中nod,这个内存溢出将解释为什么它会被更改.下图将(尝试)说明这一点.假设你的nod定义是:
int nod[3][2];
Run Code Online (Sandbox Code Playgroud)
但你试图设置nod[1-3][1-2]而不是nod[0-2][0-1]:
+-----------+
+0000 | nod[0][0] |
+-----------+
+0004 | nod[0][1] |
+-----------+
+0008 | nod[1][0] |
+-----------+
+000c | nod[1][1] |
+-----------+
+0010 | nod[2][0] |
+-----------+
+0014 | nod[2][1] |
+-----------+
+0018 | len[0] | and nod[3][0], should you be foolish enough to try :-)
+-----------+
+001c | len[1] | and nod[3][1] *
+-----------+
+0020 | len[2] | and nod[3][2] *
+-----------+
Run Code Online (Sandbox Code Playgroud)
C/C++不会检查常规数组边界是否有溢出.所以,如果你试图设置nod[3][something-or-other],你会发现自己遇到的麻烦与你的问题所描述的非常相似.
您正在使用的位模式(3和4)分别等同于IEEE754单精度4.2x10 -45和5.6x10 -45,因此它们0.0000在打印时肯定会给出(因为您似乎没有使用格式字符串会给你更准确的价值).
测试该理论的一个好方法是len在设置相关nod变量之前和之后立即输出变量,如:
printf ("before: len1 = %f, len2 = %f\n", len[1], len[2]);
nod[3][1] = 3;
nod[3][2] = 4;
printf ("after : len1 = %f, len2 = %f\n", len[1], len[2]);
Run Code Online (Sandbox Code Playgroud)
关于如何在存储器中布置变量的实际细节可能与上面描述的不同,但理论仍然成立.
如果事实证明是两个可能的解决方案.
int nod[4][3].| 归档时间: |
|
| 查看次数: |
553 次 |
| 最近记录: |