以指针形式声明的数组存储在何处?以char* str调用fgets的场景为例
问题的核心混淆点:一定要区分两个独立的存储概念
很多人搞不清这类问题,本质是把两个完全独立的内存分配逻辑混在了一起:
char* str这个指针变量自身的存储空间str这个变量中存储的地址所指向的目标内存的存储空间
这两块内存可能在完全不同的区域,没有绑定关系。
对应你给出的代码场景逐点拆解
- 先说
str这个指针变量本身的位置
如果char* str;是函数内部的局部声明,那么这个指针变量本身的空间默认分配在栈上:64位系统下占8字节、32位系统下占4字节,仅用来存储一个内存地址值。只有当这个声明是全局变量、静态变量时,它本身才会被放到全局静态存储区。 - 这段代码里根本没有涉及堆内存的分配
堆内存的唯一分配逻辑是你主动调用malloc/calloc/realloc这类函数手动申请,你给出的代码里没有任何这类调用,甚至连合法的可写内存都不存在:
你声明的str是未初始化的野指针,它存的地址值是栈上残留的随机垃圾值,既不指向合法的栈数组,也不指向你申请的堆内存,直接把它传给fgets属于典型的非法内存写入,大概率会触发段错误崩溃。 - 直接回应你的疑问:这个
char*对应的存储空间完全不在堆上
你在代码里看到的char*变量本身只是栈上的一个地址占位符,和堆没有任何关系。
几个容易搞混的对照场景
- 如果你写
char* str = malloc(40);:此时str这个指针本身仍然在栈上(作为局部变量),只是它存储的地址指向了从堆上申请的40字节可写内存,这时候才会涉及堆内存的使用。 - 如果你写
char str[40];:此时你是在栈上直接开辟了40字节的连续字符存储区,str作为数组首地址的常量,整个数组的存储空间都在栈上,这时候把它传给fgets是合法的。
内容的提问来源于stack exchange,提问作者Alberto Tiraboschi
相关产品推荐
相关产品推荐

