gpt4 book ai didi

c++ - 直接用变量设置指针意味着什么?

转载 作者:行者123 更新时间:2023-11-30 21:19:05 26 4
gpt4 key购买 nike

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.

并发现,通过直接将值分配给指针而不使用 malloc 或 null 初始化,意味着我们对编译器说,嘿 CPU,在内存中创建一个空间来在给定的确切地址处存储整数值,在本例中为 20。所以基本上是告诉编译器在地址为 20 的 RAM 中为 INT 腾出一个位置。通过这样做,我们正在接触系统内存或非法空间。

但我不明白的是,

  1. How the integer 20 can directly be referenced as a memory?

  2. What happens when we do the same for float or char? for example float *ptr = 20.25

  3. I tried directly converting c code to assembly with a website, for a legal and illegal pointer example, where I see that the same registers are called, same MOV operations are done, And no explicit "MAKE SPACE AT given ADDRESS" instructions were set.

  4. 最后,当我们通过 char 声明字符串时到底会发生什么*ptr =“你好”?

我已经尝试了一切可能的方法来理解这一点,但还是不行。你们能指出我正确的方向吗?谢谢...

最佳答案

How the integer 20 can directly be referenced as a memory?

使用我的 C++ 编译器,它无法编译:我收到此错误:

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 个字节的内存位置)。

请注意,在大多数操作系统上,它不是可用的内存地址;大多数操作系统将地址空间的前几页标记为“不可读/不可写”,这样当有人试图取消引用 NULL 指针时,它们可能会导致进程崩溃(否则会导致进程以较小的速度读取或写入内存)从内存空间开始的偏移量)

What happens when we do the same for float or char? for example float *ptr = 20.25

这些类型无法编译,因为浮点(或字符)值作为内存地址没有意义。在大多数环境中,内存地址是距内存空间顶部的整数偏移量,因此如果您想将其指定为常量(顺便说一句,您通常不想这样做,除非您在非常低的级别上工作,例如直接在嵌入式 Controller 中寻址 DMA 硬件),它需要是一个整数常量。

And no explicit "MAKE SPACE AT given ADDRESS" instructions were set.

这是预料之中的——设置一个指向值的指针不会隐式地为任何东西腾出空间,它只是将指针设置为指向指定常量的内存地址。

Lastly, What exactly happens when we declare strings by doing char *ptr = "Hello"?

在这种情况下,编译器会识别出您已声明一个字符串常量,并将该字符串作为只读数组添加到进程的内存空间中。完成此操作后,它可以将指针设置为指向该数组的开头。请注意,此行为特定于字符串常量,不会延续到 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++ - 直接用变量设置指针意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58785802/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com