使用MinGW 4.6.2(4.7.x似乎不是sourceforge上的“最新版本”,所以安装了这个版本)
void test(int *in)
{
*in = 0;
}
int main()
{
int dat;
test(dat);
return dat;
}
你可能知道这会在c项目中发出警告。
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
已启用或编译为c程序。
dat
未初始化且程序继续进行(并且不会发生分段错误)。dat
被初始化为42,程序继续进行(并且会出现seg-fault)。为什么离开dat
未初始化导致没有seg-fault(可能偶然?),而情况2导致seg-fault(可能试图将值分配给内存位置)?
好奇心:f
代表-fpermissive
代表的是什么? (似乎多余)
答案 0 :(得分:3)
该程序按原样具有未定义的行为,因此尝试推理其行为毫无意义,但无论如何......
test()
函数需要一个指向int
的指针。该指针将被取消引用并用于设置它指向的int
。但是,你没有向它传递一个指向int
但是未初始化int
的指针 - 所以它会尝试将该变量中的任何垃圾值解释为内存地址,然后访问它后面的对象 - 和繁荣。
如果您想正确调用该函数,则需要编写
test(&dat);
代替。
f在
-fpermissive
中代表什么,也许是旗帜?
不,据我所知,它代表“功能”。 (但在-fpermissive
的情况下,我会说它代表“你的代码是 f ..如果你使用这个标志,那就是ked ...” )
答案 1 :(得分:2)
正如警告所说passing argument 1 of 'test' makes pointer from integer
,你试图从一个传递整数值的地址中取一些东西。它可能是任何东西。
当你传递值42时,编译器被迫在地址42
获取一些值,这个值不是为用户保留的,而你正在获得Segfault.By默认编译器正在分配一些值,后来这个值变为地址,不知何故,你很幸运,你没有得到Segment故障。
答案 2 :(得分:1)
默认情况下,在c中发生按值传递。
void test(int *in)
{
*in = 0;
}
test(dat); // passing value
这里你传递的是未初始化的数据。它将考虑垃圾值。因此,您试图将garabage值作为测试函数中的内存地址。这是未定义的行为。相反,你可以试试这个。
test(&data);
来到你的问题。
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.