今天我和海合会有一次奇怪的邂逅。请考虑以下代码:

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.........*/

还有一个变化:
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

长度[1]=1.0;长度[2]=2.0;
for(i=1;i<=nnod;i++)
  for(j=1;j<=nfree;j++)
/* blah blah.........*/

唯一的区别是用粗体突出显示。问题是:
当随后打印长度时,第一个代码将len[1]和len[2]打印为0.0000(并在表达式中使用),而第二个代码将打印并使用这些变量的正确值。
怎么了?我完全糊涂了。
注意:len在其他地方没有被修改。

最佳答案

您需要向我们展示nod的定义。很有可能(基于数组从1开始,而不是从0开始)重写内存。
例如,如果nod定义为:

int nod[3][2];

可能的数组下标是0-20-1,而不是1-31-2
nod[0][0]   nod[1][0]   nod[2][0]
nod[0][1]   nod[1][1]   nod[2][1]

如果是这样的话,你的记忆几乎肯定是写得太多了,在这种情况下,所有的赌注都被取消了。你可能会破坏任何其他数据。
如果len紧跟在nod之后放在内存中,则此内存溢出将解释其更改的原因。下图将(试图)说明这一点。假设您的nod定义是:
int nod[3][2];

但您尝试设置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] *
      +-----------+

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]);

关于变量如何在内存中布局的实际细节可能与上述不同,但理论仍然适用。
两个可能的解决方案,如果这是问题的话。
使用零基数组作为C/C++的意图;或者
为它们定义足够的空间来处理您的异常使用,例如int nod[4][3]

关于c++ - 数组值自动更改为0,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1284277/

10-10 20:31