【问题标题】:Why do I get different results from C code running in gcc and Visual Studio running it为什么我从在 gcc 中运行的 C 代码和运行它的 Visual Studio 得到不同的结果
【发布时间】:2022-01-13 09:12:57
【问题描述】:
#include <stdio.h>

int A()
{
    int array[10];
    int i;
    for (int i = 0; i < 10; i++)
    {
        array[i] = i;
    }
}

int B()
{
    int array[10];
    int i;
    for (int i = 0; i < 10; i++)
    {
        printf("%d", array[i]);
    }
}

int main()
{
    A();
    B();
}

这是我的代码,我认为数组应该在函数 B 中重新初始化一次,所以我认为 Visual Studio 的答案是我想要的,但我不明白为什么 GCC 会返回这个答案

【问题讨论】:

  • 因为未定义的行为。任何事情都有可能发生。
  • 你在不同函数中的变量是不同的变量。 array in B() 使用时未初始化。
  • 你期望什么输出,为什么?

标签: c scope initialization undefined-behavior function-definition


【解决方案1】:

对于这两个函数的初学者,变量i 在数组声明之后声明

int array[10];
int i;

未使用。

代码具有未定义的行为,因为您试图在函数 B 中输出未初始化的本地数组。

虽然函数的返回类型不是void,但函数也什么也不返回。

int B()
{
    int array[10];
    int i;
    for (int i = 0; i < 10; i++)
    {
        printf("%d", array[i]);
    }
}

您需要的是以下内容

#include <stdio.h>

void A( int array[], int n )
{
    for ( int i = 0; i < n; i++)
    {
        array[i] = i;
    }
}

void B( const int array[], int n )
{
    for (int i = 0; i < n; i++)
    {
        printf("%d ", array[i]);
    }
    putchar( '\n' );
}

int main( void )
{
    enum { N = 10 };
    int array[N];

    A( array, N );
    B( array, N );
}

【讨论】:

  • 是的,我把函数的返回值写错了,感谢改进我的代码。
【解决方案2】:

您在A() 中为您的数组分配内存,然后初始化。 通常局部变量是在栈上分配的。

从函数A() 返回后,堆栈被清理。 然后调用B() 并将返回地址压入堆栈。 B() 可能会推送 rbp 以更正堆栈帧,然后在堆栈上为恰好与 A() 中使用的数组相似的数组分配内存。由于没有人费心初始化内存,它仍将包含与以前相同的值。但这应该被认为是巧合。

不同的编译器将使用不同的方式来管理内存。此外,Windows 使用不同于 Linux 的另一种调用约定。所有可以解释差异的因素。

主要问题是您使用的是未初始化的内存,这几乎会导致任何问题。

【讨论】:

  • 感谢您的回答。我的理解是函数B运行时,栈中的数组初始化位置和A一样
  • @tang Saring 相同的位置是可能的,也可能发生。但这绝不会让您依赖它。非静态局部变量未初始化。阅读它们会导致未定义的行为。不要这样做。故事结束。
猜你喜欢
  • 2022-01-23
  • 2016-08-16
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多