动态变量可以具有的位置是否有限制,静态变量是否有所不同? 进程的内存中是否存在不能分配动态变量而可以分配静态变量的分区?


我正在使用C语言的在线IDE,并try 使用指针,这时我注意到动态分配的变量在打印时方向似乎更短. (示例)

  • 静态变量指针:0x7ffc49f6fbe4
  • 动态变量指针:0x15512a0

起初,这让我认为动态变量的指针比静态变量的指针小. 我try 了一些方法来了解情况是否如此:首先,我try 查看各种类型的指针,以了解这是否仅适用于动态变量. 然后,我try 了使用动态和静态变量指针的sizeof():

  int a;
  int *b=malloc(sizeof(int));
  printf("%lu\n%lu",sizeof(&a),sizeof(b));

两者都返回了8个字节.我计算了打印的十六进制值中的字节数.静态变量有16个十六进制数字=8个字节,而动态变量有7个十六进制数字=4个字节.字节的减半给了我另一个 idea :也许静态和动态方向在内存中有不同的部分可以分配,所以当我打印动态指针的方向时,它不会费心给我整个方向,只打印动态指针可以占用的部分.当我将方向加1时,这一点得到了加强,最后一个十六进制在两个指针中都发生了变化.如果我添加了足够的内容,迫使 fingerprint 显示另一个数字,它也会显示新的数字:

  int a, *b;
  int *c=malloc(sizeof(int));
  printf("%p\n%p\n%p",&b,c,c+67108864);

显示:

0x7fffc15b5920
0x211e2a0
0x1211e2a0

我试着找这个问题,但找不到,所以我做了.

推荐答案

各种物体的位置并没有什么特别之处.它们在哪里只是一个需要组织内存以支持各种功能的问题.在这样做的过程中,人们会做出武断的 Select ,而其他 Select 也是可能的.

有各种软件参与规划程序的内存布局并将其加载到内存中.静态对象是在程序的可执行文件中定义的,在编译器和链接过程中放在那里.程序加载器读取可执行文件以查看这些对象需要多少内存,并在正在创建的进程的虚拟地址空间中为它们规划一些空间.

进程也有一个堆栈,所以程序加载器为它规划了一些空间.通常,可执行文件包含有关程序需要多少堆栈空间的信息.

当程序启动时,In中的软件将初始化C环境,包括为动态分配规划空间.

这样做很复杂,例如当程序调用动态加载的库中的 routine 时,需要加载额外的静态对象,从而为进程中的新线程堆栈保留额外的空间.本质上,编写加载程序的软件和管理进程内内存的软件的人已经为此制定了计划,因此,在任何特定的操作系统上,默认布局在地址空间的某个部分具有静态对象,在另一部分具有堆栈,在另一部分具有动态分配的内存.

…另一个 idea :也许…当我打印动态指针的方向时,它不会费心给我整个方向,而只是打印动态指针可以占据的部分.

当您打印带有%p的指针时,将打印有关该指针的完整信息.(请注意,以这种方式打印时,指针应转换为(void *).)它不仅仅是地址信息的一部分.如果某些指针的%p输出比其他指针的位数多或少,这只是因为显示它们的值所需的位数或多或少,与一般的数字一样.

C++相关问答推荐

POSIX文件描述符位置

如何在C中只使用一个带双方括号([i][j])访问语法的malloc来分配动态大小的2d数组?

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

数据包未从DPDK端口传输到内核端口

使用额外的公共参数自定义printf

为什么sscanf不能正确地从这个字符串格式中提取所有数字?

使用C时,Windows CMD中的argc参数是否包含重定向命令?

在C23中使用_GENERIC实现带有右值的IS_POINTER(P)?

在C++中通过空指针隐式访问常量变量的值

如何使用指向 struct 数组的指针并访问数组中特定索引处的 struct

限制不同类型的限定符

如何在C++中处理按键

为什么函数是按照定义的顺序执行的,而不是按照从avr-c中的int main()调用的顺序执行的?

#定义SSL_CONNECTION_NO_CONST

C代码可以在在线编译器上运行,但不能在Leetcode上运行

从另一个宏函数调用C宏

当另一个指向 const 的指针观察到数据时,通过指针更改数据是否安全?

将数组中的所有元素初始化为 struct 中的相同值

使用 GCC 将一个函数中初始化的 struct 体实例通过指针传递到 C 中的另一个函数会产生不同的结果

如何修复数组数据与列标题未对齐的问题?