指针行为异常
Pointer behaves strangely
我是一名编程和 C++ 新手。如果能提供一些帮助,我将不胜感激。
以下程序(在 c++ 中)在编译或 运行 时没有遇到任何问题:
int main()
{
int b = 5;
int*a = &b;
*(a+5) = 6;
return 0;
}
但根据我了解到的一切,它应该不起作用,因为 a 是指向单个变量的指针。我在这里错过了什么?
您的程序在编译时应该确实没有遇到任何问题。都是关于编译的有效代码。
但是它会在运行时遇到未定义的行为,因为 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
表示 a
指向的地址 5 "ints"。由于 a
指向单个整数 b
,所以无法保证这样的地址。有趣的是,它被明确定义为引用 a+1
,即使它指向内存中您不应读取或写入的位置。但是指针本身有一些保证,即它会大于 a
并且如果你从中减去 1 你会回到 a
如果你在它和 a
之间做一个 ptrdiff你会得到 1。但这只是 "one past the end" 的特殊 属性,它允许程序员指定内存范围。
是的,当您访问不在您的进程区域中的内存 space 时,它不应该工作,但也许没有人拥有该特定区域 ((a + 5)
),这不会导致 运行时间非法内存访问还是可以的。因此它是一个 UB。
该程序确实有一个未定义的行为:
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 或更高,崩溃的机会将会增加。
只是添加到现有答案中。
访问权限
*(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
我是一名编程和 C++ 新手。如果能提供一些帮助,我将不胜感激。
以下程序(在 c++ 中)在编译或 运行 时没有遇到任何问题:
int main()
{
int b = 5;
int*a = &b;
*(a+5) = 6;
return 0;
}
但根据我了解到的一切,它应该不起作用,因为 a 是指向单个变量的指针。我在这里错过了什么?
您的程序在编译时应该确实没有遇到任何问题。都是关于编译的有效代码。
但是它会在运行时遇到未定义的行为,因为 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
表示 a
指向的地址 5 "ints"。由于 a
指向单个整数 b
,所以无法保证这样的地址。有趣的是,它被明确定义为引用 a+1
,即使它指向内存中您不应读取或写入的位置。但是指针本身有一些保证,即它会大于 a
并且如果你从中减去 1 你会回到 a
如果你在它和 a
之间做一个 ptrdiff你会得到 1。但这只是 "one past the end" 的特殊 属性,它允许程序员指定内存范围。
是的,当您访问不在您的进程区域中的内存 space 时,它不应该工作,但也许没有人拥有该特定区域 ((a + 5)
),这不会导致 运行时间非法内存访问还是可以的。因此它是一个 UB。
该程序确实有一个未定义的行为:
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 或更高,崩溃的机会将会增加。
只是添加到现有答案中。
访问权限
*(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