我在软件安全上启动了一个单元 - 在一些预读中,我遇到了以下指针语法,我不确定是否理解。
int x = 20;
int* p = &x;
int k = *(p+1);
示例中的 k 是什么?
我知道我是否有这样的数组:
int j[10] = {0};
int k = *(j+1);
此类语法将在数组 j 的位置1处取消引用int(系统' s sizeof(int)
)。
那么这如何与上面的非数组示例一起使用?
答案 0 :(得分:2)
向指针添加*(p+1)
的指针算术int
语法等同于p[i]
。它假定p
指向足够大小的块,否则取消引用会导致未定义的行为。
请注意,您不需要使用数组new
初始化指针。您可以在自动内存中使用数组,指向现有数组,甚至指向另一个数组的中间,如下所示:
int data[20] = {0, 1, 2, 3, 4, 5, 6, ...};
int *p = &data[5]; // Point to element at index five
int x = *(p+1); // Access element at index six
答案 1 :(得分:2)
指向值的指针与指向数组第一个元素的指针无法区分。
因此int*p = &x
是指向数组的第一个元素的指针,其中只分配了一个元素。现在*(p+1)
正在访问该数组的第二个元素 - 这是访问元素超出数组范围并且是未定义的行为(Array index out of bound in C)。此类操作的有效结果范围从世界销毁到无操作。
一个可能的情况是*(p+1)
将引用p
本身的整体/部分,因为通常变量是按顺序分配的。所以很有可能没有什么了不起的事情,并且bug会在一段时间内被忽视。代码审查和一般关注此类代码是防止这些代码的良好做法。
答案 2 :(得分:1)
在第一个示例中,您将在x之后直接指向内存中的项目。 x之后的内存将是p的地址,包含在p中。
请记住,这是一种概括,这可能会根据一些事情而改变,因此它是未定义的行为。尝试添加以下行:
printf("&x: %p\n p: %p\n&k: %p\n k: %08x\n", &x, p, &k, k);
并在main中运行代码。这应该打印出内存地址和k的十六进制值。它应该让你更清楚地了解内存中究竟发生了什么。
请注意,如果更改变量的顺序,输出将会更改。你应该习惯记忆是如何工作的以及为什么这种事情是未定义的行为(因此除了学习目的之外不应该用于任何事情)。
答案 3 :(得分:1)
这是我用这种语法编写的代码示例,它将一个int分解为它的组成字节。
#include <stdio.h>
int main(void) {
int i = 9;
int* p = &i;
char* c = (char*)&i;
printf("%08X\n", *c);
printf("%08X\n", *(c+1));
printf("%08X\n", *(c+2));
printf("%08X\n", *(c+3));
return 0;
}
➜ tmp git:(master) ✗ ./q3
00000009
00000000
00000000
00000000