简体   繁体   English

指针类型转换

[英]pointer typecasting

int main()
{
int *p,*q;
p=(int *)1000;
q=(int *)2000;
printf("%d:%d:%d",q,p,(q-p));
}

output 输出

2000:1000:250

1.I cannot understand p=(int *)1000; 1.我无法理解p=(int *)1000; line, does this mean that p is pointing to 1000 address location? 行,这是否意味着p指向1000个地址位置? what if I do *p=22 does this value is stored at 1000 address and overwrite the existing value? 如果我做*p=22 ,该值存储在1000个地址并覆盖现有值怎么办? If it overwrites the value, what if another program is working with 1000 address space? 如果它覆盖该值,那么如果另一个程序正在使用1000地址空间怎么办?

  1. how qp=250 ? qp=250如何?

EDIT: I tried printf("%u:%u:%u",q,p,(qp)); 编辑:我试过printf("%u:%u:%u",q,p,(qp)); the output is the same 输出是相同的

int main()
{
int *p;
int i=5;
p=&i;
printf("%u:%d",p,i);
return 0;
}

the output 输出

3214158860:5
  1. does this mean the addresses used by compiler are integers? 这是否意味着编译器使用的地址是整数? there is no difference between normal integers and address integers? 普通整数和地址整数之间没有区别吗?

does this mean that p is pointing to 1000 address location? 这是否意味着p指向1000个地址位置?

Yes. 是。

what if I do *p=22 如果我做* p = 22怎么办

It's invoking undefined behavior - your program will most likely crash with a segfault. 它正在调用未定义的行为-您的程序很可能会因段错误而崩溃。

Note that in modern OSes, addresses are virtual - you can't overwrite an other process' adress space like this, but you can attempt writing to an invalid memory location in your own process' address space. 请注意,在现代操作系统中,地址是虚拟的-您不能像这样覆盖其他进程的地址空间,但是可以尝试在自己进程的地址空间中写入无效的内存位置。

how qp=250? qp = 250如何?

Because pointer arithmetic works like this (in order to be compatible with array indexing). 因为指针算法的工作原理是这样的(为了与数组索引兼容)。 The difference of two pointers is the difference of their value divided by sizeof(*ptr) . 两个指针的区别是它们的值之差除以sizeof(*ptr) Similarly, adding n to a pointer ptr of type T results in a numeric value ptr + n * sizeof(T) . 类似地,将n添加到类型T的指针ptr会得到数值ptr + n * sizeof(T)

Read this on pointers. 阅读有关指针的内容。

does this mean the addresses used by compiler are integers? 这是否意味着编译器使用的地址是整数?

That "used by compiler" part is not even necessary. 甚至没有必要“由编译器使用”部分。 Addresses are integers, it's just an abstraction in C that we have nice pointers to ease our life. 地址整数,它只是C语言的一种抽象,我们有很好的指针来简化我们的生活。 If you were coding in assembly, you would just treat them as unsigned integers. 如果您使用汇编语言进行编码,则只需将它们视为无符号整数即可。

By the way, writing 顺便说一下

printf("%u:%d", p, i);

is also undefined behavior - the %u format specifier expects an unsigned int , and not a pointer. 也是未定义的行为- %u格式说明符期望unsigned int ,而不是指针。 To print a pointer, use %p : 要打印指针,请使用%p

printf("%p:%d", (void *)p, i);

Yes, with *p=22 you write to 1000 address. 是的,使用*p=22您将写入1000个地址。

qp is 250 because size of int is 4 so it's 2000-1000/4=250 qp是250,因为int的大小是4,所以它是2000-1000 / 4 = 250

The meaning of p = (int *) 1000 is implementation-defined. p = (int *) 1000的含义是实现定义的。 But yes, in a typical implementation it will make p to point to address 1000 . 但是,是的,在典型的实现中,它将使p指向地址1000

Doing *p = 22 afterwards will indeed attempt to store 22 at address 1000 . 之后执行*p = 22确实会尝试将22存储在地址1000 However, in general case this attempt will lead to undefined behavior, since you are not allowed to just write data to arbitrary memory locations. 但是,在一般情况下,这种尝试将导致不确定的行为,因为不允许您仅将数据写入任意内存位置。 You have to allocate memory in one way or another in order to be able to use it. 您必须以一种或另一种方式分配内存才能使用它。 In your example you didn't make any effort to allocate anything at address 1000 . 在您的示例中,您没有做出任何努力来分配地址1000任何内容。 This means that most likely your program will simply crash, because it attempted to write data to a memory region that was not properly allocated. 这意味着您的程序很可能会崩溃,因为它试图将数据写入未正确分配的内存区域。 (Additionally, on many platforms in order to access data through pointers these pointers must point to properly aligned locations.) (此外,在许多平台上,为了通过指针访问数据,这些指针必须指向正确对齐的位置。)

Even if you somehow succeed succeed in writing your 22 at address 1000 , it does not mean that it will in any way affect "other programs". 即使您以某种方式成功完成了在地址1000处写入22 ,也并不意味着它将以任何方式影响“其他程序”。 On some old platforms it would (like DOS, fro one example). 在某些旧平台上(例如DOS,例如)。 But modern platforms implement independent virtual memory for each running program (process). 但是现代平台为每个正在运行的程序(进程)实现了独立的虚拟内存。 This means that each running process has its own separate address 1000 and it cannot see the other program's address 1000 . 这意味着每个正在运行的进程都有其自己的单独地址1000并且看不到另一个程序的地址1000

  1. Yes, p is pointing to virtual address 1000. If you use *p = 22; 是的, p指向虚拟地址1000 *p = 22; , you are likely to get a segmentation fault; ,您很可能会遇到细分错误; quite often, the whole first 1024 bytes are invalid for reading or writing. 通常,整个前1024个字节对于读取或写入都是无效的。 It can't affect another program assuming you have virtual memory; 假设您有虚拟内存,它不会影响其他程序; each program has its own virtual address space. 每个程序都有其自己的虚拟地址空间。

  2. The value of q - p is the number of units of sizeof(*p) or sizeof(*q) or sizeof(int) between the two addresses. q - p的值是两个地址之间的sizeof(*p)sizeof(*q)sizeof(int)的单位数。

Casting arbitrary integers to pointers is undefined behavior. 将任意整数强制转换为指针是未定义的行为。 Anything can happen including nothing, a segmentation fault or silently overwriting other processes' memory (unlikely in the modern virtual memory models). 任何事情都可能发生,包括什么都没有,分段错误或无声地覆盖其他进程的内存(在现代虚拟内存模型中不太可能)。

But we used to use absolute addresses like this back in the real mode DOS days to access interrupt tables and BIOS variables :) 但是我们曾经在DOS实模式下使用过这样的绝对地址来访问中断表和BIOS变量:)

About qp == 250 , it's the result of semantics of pointer arithmetic. 关于qp == 250 ,这是指针算术语义的结果。 Apparently sizeof int is 4 in your system. 在您的系统中, sizeof int显然是4。 So when you add 1 to an int pointer it actually gets incremented by 4 so it points to the next int not the next byte. 因此,当您将1加到int指针时,它实际上会增加4,因此它指向下一个int而不是下一个字节。 This behavior helps with array access. 此行为有助于阵列访问。

does this mean that p is pointing to 1000 address location?

yes. 是。 But this 1000 address may belong to some other processes address.In this case, You illegally accessing the memory of another process's address space. 但是这个1000地址可能属于其他一些进程地址。在这种情况下,您非法访问了另一个进程的地址空间的内存。 This may results in segmentation fault. 这可能会导致分割错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM