我是编程和c ++新手。我很感激你的帮助。
以下程序(在c ++中)在编译或运行时都没有遇到任何问题:
int main()
{
int b = 5;
int*a = &b;
*(a+5) = 6;
return 0;
}
但根据我所学到的一切,它不应该起作用,因为a是指向单个变量的指针。我在这里缺少什么?
答案 0 :(得分:6)
您的程序在编译时确实不会遇到任何问题。它是关于编译的所有有效代码。
但是,它会在运行时遇到未定义的行为,因为a+5
不是有效的地址。
如果你想知道它为什么要编译,你可以写这样的代码:
int func( int * buf, size_t size )
{
for( size_t i = 0; i < size; ++i )
{
*(buf + size) = static_cast<int>(i); // or (int)i in C
}
}
int main()
{
int buf[ 6 ];
func( buf, 6 );
}
在您的代码中a
是指向内存的指针。 a + 5
表示地址5&#34; ints&#34;从a
点开始。由于a
指向单个整数b
,因此无法保证此类地址。有趣的是,它被明确定义为引用a+1
,即使它指向内存中您不应该读取或写入的位置。但是指针本身有一些保证,即它会大于a
,如果你从它中减去1,你将回到a
,如果你在它和a
之间做了一个ptrdiff你会得到1.但这只是一个特殊的属性&#34;一个过去的结束&#34;它允许程序员指定内存范围。
答案 1 :(得分:1)
程序确实有未定义的行为:
int main()
{
//This cause the loading of the "main" function to allocate memory for variable b
//It could be in a memory page that was already allocated to the program
//or in a new allocated page.
int b = 5;
//Here a just getting the address of variable b.
int*a = &b;
//This is the undefined behavior and can end up in two cases:
// 1. If (a+5) value is in a memory space that is allocated to the application.
// Then no runtime error will happen, and the value will be writing there.
// probably dirting some other value, and can cause an undefined behavior later
// in the application execution.
// 2. If (a+5) value is in a memory space that wasn't allocated to the application.
// the application will crash
*(a+5) = 6;
return 0;
}
现在,由于页面大小可能是4096而b在页面中的某个位置,因此* b + 5在大多数情况下仍然在同一页面中。如果你想挑战它,可以将它从5改为5000或更高,崩溃的几率会增加。
答案 2 :(得分:0)
是的,当您访问不在您的进程区域中的内存空间时,它应该不起作用,但可能没有人拥有该特定区域((a + 5)
),该区域不会导致运行时非法内存访问或它能够。因此它是一个UB。
答案 3 :(得分:0)
只需添加现有答案。
访问
*(a+5) = a[5]
所以这是您未分配的位置。
在数组的情况下说
int a[6];
您拥有从a[0]
到a[5]
的有效访问权限,其中a[5]
是数组的最后一个元素,而a[6]
之类的任何进一步访问都会导致未定义的行为地点不是由您分配的。
同样,你只需要一个像
这样的整数int b=5;
int *a = &b;
a是指向&b
的指针,即b的地址。
因此对此的有效访问只是a[0]
,这是您在堆栈上分配的唯一位置。
a[1] a[2]...
之类的任何其他访问都会导致未定义的行为。
如果您有类似
的内容,则访问权限为有效int b[6];
int *a = b;
现在a[5]
将给出数组b