-2

使用 MinGW 4.6.2(4.7.x 似乎不是 sourceforge 上的“最新”,所以安装了这个)

void test(int *in)
{
    *in = 0;
}
int main()
{
    int dat;
    test(dat);
    return dat;
}

正如您可能知道的那样,这将在 ac 项目中发出警告。

dirpath\fileName.c|8|warning: passing argument 1 of 'test' makes pointer from integer without a cast [enabled by default]

和一个 c++ 项目中的 2 个错误。

dirpath\fileName.cpp|8|error: invalid conversion from 'int' to 'int*' [-fpermissive]|

dirpath\fileName.cpp|1|error: initializing argument 1 of 'void test(int*)' [-fpermissive]|

我的问题是,在以下两种情况下(在内存中)究竟发生了什么,假设-fpermissive启用或编译为 ac 程序。

  1. dat未初始化并且程序继续(并且没有发生分段错误)。
  2. dat被初始化为 42,并且程序继续(并且执行 seg-fault)。

为什么dat未初始化会导致没有段错误(可能是偶然的?),而情况 2 会导致段错误(可能是试图将值分配给内存位置)?

好奇心f-fpermissive, flag 中代表什么?(似乎多余)

4

3 回答 3

3

该程序按原样具有未定义的行为,因此尝试推理其行为是没有意义的,但无论如何......

test()函数需要一个指向 的指针int。该指针将被取消引用并用于设置int它指向的。但是,您不会将指针传递给它,int而是将其传递给未初始化的指针int-因此它将尝试将该变量中的任何垃圾值解释为内存地址,然后访问其后面的对象-然后繁荣。

如果您想正确调用该函数,则需要编写

test(&dat);

反而。

f 代表什么-fpermissive,也许是标志?

不,据我所知,它代表“功能”。(但在 的情况下-fpermissive,我会说它代表“如果你使用这个标志,你的代码就是f ..ked”......)

于 2013-07-26T04:45:17.947 回答
2

正如警告所说passing argument 1 of 'test' makes pointer from integer,您正试图从作为传递整数值的地址中获取某些东西。它可能是任何东西。

当您传递值 42 时,编译器被迫在未为用户保留的地址处获取一些值,42并且您正在获得 Segfault。默认情况下,编译器正在分配一些值,然后这些值将成为地址,不知何故,您很幸运您不会因此而遇到段错误。

于 2013-07-26T04:49:33.200 回答
1

在 c 中,默认情况下会按值传递

void test(int *in)
{
   *in = 0;
}

test(dat); // passing value

here you are passing dat which is uninitialized. It will consider a garbage value. So you are trying to make the garabage value to act as a memory address in the test function. It is undefined behaviour. Instead you can try this.

test(&data);

Coming to your question.

Q. dat is uninitialized and the program proceeds (and no segmentation fault occurs).
A. This is an undefined behaviour because your are passing a garbage value. If your
   garbage value is a proper memory address then it will not cause segmentation error.
   If it is not proper, it will cause segmentaion error. So it happend at runtime 
   dynamically and can give either segmentation fault or can run.  

Q. dat is initialized to 42, and the program proceeds (and does seg-fault)
A. Here you have initialized dat to 42. By default c works on pass by value definition.
   So you are passing 42 to test. test will consider 42 as a memory location, which 
   is not a proper memory location so it cause segmentation error.
于 2013-07-26T06:08:45.097 回答