【问题标题】:C program is behaving giving weird values in Windows but works fine in UbuntuC 程序在 Windows 中表现出奇怪的值,但在 Ubuntu 中运行良好
【发布时间】:2016-09-05 20:48:47
【问题描述】:

我在我的笔记本电脑上使用 Ubuntu 为学校的一项小任务编写了一个程序。我在编写程序时没有遇到任何问题。它工作得很好,并做了它应该做的一切。但是当我将它移到我的 Windows PC 上时,它给了我一些非常奇怪的值,我似乎无法弄清楚它有什么问题。我在 Ubuntu 和 Windows 上都使用相同的 IDE,CodeBlocks 16.01。我已经尝试解决这个问题几个小时,但我卡住了,所以我非常感谢一些帮助。

例如,如果我在每次提示时输入值 50,我将在 while 循环后的两个 printf 方法中得到 200 的结果,就像它应该是因为 50+50+50+50 等于 200。但是在 Windows 中我在 total_weight 中得到 240,在 total_height 中得到 100,这对我来说没有任何意义。这是什么原因?

#include <stdio.h>
#include <stdlib.h>

int main()
{
int weights[3], heights[3], i = 0;
int total_weight, total_height;

while (i <= 3)
{
    printf("Person %d, enter your weight (kg): ",i+1);
    scanf("%d",&weights[i]);
    printf("Person %d, enter your height (cm): ",i+1);
    scanf("%d", &heights[i]);

    //Calculations for total weight and total length of all the people
    total_weight = total_weight + weights[i];
    total_height = total_height + heights[i];

    printf("\n\tPerson %d's weight and height: %dkg, %dcm\n\n", i+1, weights[i], heights[i]);
    i++;
}

//Printing the results of the earlier calculations
printf("\tTotal weight of everyone: %d\n", total_weight);
printf("\tTotal height of everyone: %d\n", total_height);

return 0;

}

【问题讨论】:

  • int total_weight, total_height; - 你认为这行之后的 total_weight 和 total_height 的值是多少?

标签: c arrays


【解决方案1】:

你的数组溢出了。您在每次购买中输入 4 个值,仅分配 3 个空间。

【讨论】:

  • 我尝试在数组中分配更多空间,现在我收到的值仍然是 total_weight 中的 240 和 total_height int 中的 6899064。而且分配了 3 个空间的数组仍然可以在我的 Ubuntu 上运行,这怎么可能?
  • 它有时会起作用的原因是某些编译器,尤其是当它们没有优化时,会用额外的空间填充局部变量以用于调试或其他信息。但是,正如其他人指出的那样,这实际上与您遇到的问题无关,即未初始化的 total_weight 和 total_height 变量。
【解决方案2】:

您正在使用未初始化的total_heighttotal_weight

int total_weight, total_height; 

/* ... */
total_weight = total_weight + weights[i];
total_height = total_height + heights[i];

它们应该用零初始化:

int total_weight = 0, total_height = 0; 

另外,当i == 3 你试图从weights / heights 数组中访问内存时。可以通过两种方式解决:

  1. 不允许通过条件更正访问第四个元素:while(i &lt; 3) {
  2. 声明更强大的数组int weights[4], heights[4];

【讨论】:

    【解决方案3】:

    在你的代码中,通过说

     while (i <= 3)
    

    你要去off-by-one。这会调用undefined behavior,用于越界内存访问。

    详细地说,C 数组具有从 0 开始的索引。因此对于一个维度为 3 的数组,其有效索引范围为 0 到 2,包括 0 到 2。

    所以,你应该使用

    while (i < 3)
    

    保持在界限内。

    也就是说,在您的代码中,total_weighttotal_height 是自动局部变量,它们在未初始化的情况下使用。因此,它们包含不确定的值,使用它们会再次导致 UB。您必须将它们显式初始化为 0。

    【讨论】:

    • 起初我使用了 while (i
    • @mmollle:在表达式weights[3] 中,3 指定元素的数量,而不是最终索引。 3 个元素表示索引从 0 到 2。
    • @IInspectable 感谢您的详细说明。不过,我认为我在这一点上很清楚。 :)
    • 好吧,通过在声明语句中将 total_weight 和 total_height 设置为 0,我现在得到了正确的值。但是,当我在 Ubuntu 中运行它们时,它们如何在没有初始化的情况下工作呢?
    • @mmollle 而这些并不是唯一的问题。关于未定义的行为,这就是它的。请阅读链接的文章以进一步了解它。
    【解决方案4】:

    在 Linux(基于 Debian,如 Ubuntu)上编译您的代码

    gcc-4.9 -O3 -g3  -W -Wall -Wextra  -std=c11 stackover.c -o stackover
    

    导致以下警告:

    stackover.c: In function ‘main’:
    stackover.c:12:5: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d",&weights[i]);
         ^
    stackover.c:14:5: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d", &heights[i]);
         ^
    stackover.c:17:42: warning: iteration 3u invokes undefined behavior [-Waggressive-loop-optimizations]
         total_weight = total_weight + weights[i];
                                              ^
    stackover.c:9:7: note: containing loop
     while (i <= 3)
           ^
    stackover.c:18:18: warning: ‘total_height’ may be used uninitialized in this function [-Wmaybe-uninitialized]
         total_height = total_height + heights[i];
                      ^
    stackover.c:17:18: warning: ‘total_weight’ may be used uninitialized in this function [-Wmaybe-uninitialized]
         total_weight = total_weight + weights[i];
    

    考虑到这些,我们可以将代码更改为

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
      int weights[4], heights[4], i = 0;
      int total_weight = 0, total_height = 0;
      int res;
      // four persons
      while (i <= 3) {
        printf("Person %d, enter your weight (kg): ", i + 1);
        res = scanf("%d", &weights[i]);
        if(res != 1){
          fprintf(stderr,"Only one person, thank you\n");
          exit(EXIT_FAILURE);
        }
        printf("Person %d, enter your height (cm): ", i + 1);
        res = scanf("%d", &heights[i]);
        if(res != 1){
          fprintf(stderr,"Only one person, thank you\n");
          exit(EXIT_FAILURE);
        }
        //Calculations for total weight and total length of all the people
        total_weight = total_weight + weights[i];
        total_height = total_height + heights[i];
    
        printf("\n\tPerson %d's weight and height: %dkg, %dcm\n\n", i + 1,
               weights[i], heights[i]);
        i++;
      }
    
      //Printing the results of the earlier calculations
      printf("\tTotal weight of everyone: %d\n", total_weight);
      printf("\tTotal height of everyone: %d\n", total_height);
    
      exit(EXIT_SUCCESS);   
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      相关资源
      最近更新 更多