C++ 直接用变量设置指针意味着什么?
PS,我知道什么是指针以及如何使用指针,但有一点我很困惑。我已尝试搜索stackoverflow关于此问题的内容:C++ 直接用变量设置指针意味着什么?,c++,c,pointers,data-structures,C++,C,Pointers,Data Structures,PS,我知道什么是指针以及如何使用指针,但有一点我很困惑。我已尝试搜索stackoverflow关于此问题的内容: int *ptr = 20 //why illegal or seg fault or crash? printf("%i", *ptr) // Seg Fault printf("%i", ptr) // Output -> 20 printf("%p", &ptr) // Returns a valid address. 并发现,通过直接给指针赋值而不使用
int *ptr = 20 //why illegal or seg fault or crash?
printf("%i", *ptr) // Seg Fault
printf("%i", ptr) // Output -> 20
printf("%p", &ptr) // Returns a valid address.
并发现,通过直接给指针赋值而不使用malloc或null初始化,意味着我们要对编译器说,嘿,CPU,在内存中留出一个空间,在给定的确切地址处存储一个整数作为值,在本例中为20。基本上就是说,让编译器在ram中为一个INT,地址为20。通过这样做,我们正在接触系统内存或非法空间
但我不明白的是
使用我的C++编译器,它不编译:我得到这个错误代替:< /P>
temp.cpp:22:14: error: cannot initialize a variable of type 'int *' with an
rvalue of type 'int'
int * x = 20;
它确实编译为C,尽管有以下警告:
temp.c:12:11: warning: incompatible integer to pointer conversion initializing
'int *' with an expression of type 'int' [-Wint-conversion]
int * x = 20;
但是,这在C和C++下都可以编译:
int * x = (int *) 20;
。。。它之所以编译,是因为20是一个格式良好的内存地址(它指定了一个内存位置,距离进程内存空间的起始位置20字节)
注意,在大多数操作系统上,它不是一个可用的内存地址;大多数操作系统将地址空间的前几页标记为“不可读/不可写”,这样当有人试图取消对空指针的引用时(否则会导致进程在距内存空间起始点很小的偏移量处读取或写入内存),它们会使进程崩溃
当我们对float或char执行相同操作时会发生什么?例如浮动
*ptr=20.25
这些类型不会编译,因为浮点(或字符)值作为内存地址没有意义。在大多数环境中,内存地址是从内存空间顶部开始的整数偏移量,因此,如果您想将一个指定为常量(顺便说一句,您通常不想这样做,除非您在非常低的级别上工作,例如,在嵌入式控制器中直接寻址DMA硬件),它需要是整数常量
并且没有设置明确的“在给定地址留出空间”指令
这是意料之中的——将指针设置为值不会隐式地为任何内容留出空间,它只会将指针设置为指向指定常量的内存地址
最后,当我们通过char声明字符串时会发生什么
*ptr=“你好”
在这种情况下,编译器会识别您已声明了一个字符串常量,并将该字符串作为只读数组添加到进程的内存空间中。完成后,它可以将指针设置为指向该数组的开头。请注意,此行为特定于字符串常量,不会延续到其他数据类型,如int或float
还要注意,触发该常量相加的是字符串常量的声明,而不是指向该常量的指针的设置。例如,如果您有以下代码:
const char * s1 = "Hello";
const char * s2 = "Hello";
printf("s1=%p s2=%p\n", s1, s2);
。。。您将看到如下输出:
s1=0x104608f4e s2=0x104608f4e
。。。请注意,两个指针都指向相同的内存位置;由于这两个字符串相同且为只读,因此编译器可以通过只分配字符串数据的单个实例来节省内存
相反,如果您这样做:
const char * x = (const char *) 20;
。。。您会遇到与您在int*
示例中看到的完全相同的问题。关于C++:
这个程序格式不好。编译器不需要成功编译此程序,他们需要通知您该问题。没有从整数文本到指针的隐式转换(除了文本零)
这是非法的,因为C和C++标准是这样说的。p> 通过直接给指针赋值,而不使用malloc或null进行初始化,这意味着我们要对编译器说,嘿,CPU,在内存中留出一个空间,在给定为value的确切地址处存储一个整数,在本例中为20
一点也不像int *ptr = 20 //why illegal or seg fault or crash?
int *ptr = 20 //why illegal or seg fault or crash?
int *ptr = (int*)20;