malloc(0)的问题

栈是由编译器自动分配释放
堆由程序猿手动分配释放,如不释放最后可能由操作系统自动回收。比如用malloc分配的空间就在堆上。

这是一个前辈写的,非常详细

//main.cpp 
int a = 0; 全局初始化区 
char *p1; 全局未初始化区 
main() 
{ 
int b; 栈 
char s[] = "abc"; 栈 
char *p2; 栈 
char *p3 = "123456"; 123456\0在常量区,p3在栈上。 
static int c =0; 全局(静态)初始化区 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。 
strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"
优化成一个地方。 
} 

那么在下面这段程序

ptr = (char *)malloc(0)   /*顺便一提,在以前malloc函数返回的是char型指针,新的ANSIC规定返回值为void类型,所以如果需要赋值,要在malloc前加强制类型转换,如本题的char* 。*/
char   *ptr;
if ((ptr = (char  *)malloc(0)) ==NULL)   
     puts( "Got   a   null   pointer "); 
else 
     puts( "Got   a   valid   pointer "); 

输出结果为Got a valid pointer。
问题来了:指针为NULL时指向哪里?分配的空间为0时(即malloc(0))又指向哪里?
当使用malloc后,只有在没有足够内存的情况下会返回NULL,或是出现异常报告。
malloc(0):系统就已经帮你准备好了堆中的使用起始地址(不会为NULL)。但是你不能对该地址进行写操作(不是不允许),如果写了话,当调用free(ptr)就会产生异常报告(地址受损)。
这里还有一个描述

### C语言中的`malloc`内存分配与对齐 在C语言中,动态内存分配函数如`malloc()`会按照系统的默认设置来进行内存对齐处理。这意味着当调用`malloc(size)`时,所获得的指针指向一块已经经过适当调整后的地址,使得这块内存在被不同类型的对象占用时都能满足其对应的对齐需求[^3]。 #### 内存对齐的原因 由于现代计算机体系结构的特点,CPU并不是逐字节地访问内存而是按块读写。如果数据未正确对齐,则可能导致额外的时间开销用于跨越边界获取完整的数据项。因此,通过确保数据存储位置符合特定模式——即让每种类型的数据位于适合它大小的位置上——可以显著提升程序执行效率并减少错误发生几率[^4]。 #### `malloc`实现内部自动处理对齐 大多数情况下开发者无需担心具体的细节因为标准库已内置了合理的算法来保证新分配出来的区域总是适当地排列好以适应各种用途: - **单个元素**:对于简单变量而言,只要求它们各自的首地址能够成为自身尺寸大小的一个整数倍即可; - **复杂结构体成员之间**:针对含有多个字段的对象来说,除了考虑各个组成部分间的相对位移外还要兼顾整个实体最终占据的空间也要是对某个固定数值(通常是8或16)的最大公约数之整数倍。 ```c #include <stdio.h> #include <stdlib.h> // 定义一个简单的结构体作为例子展示 typedef struct { char c; // 占用1字节 int i; // 占用4字节,在某些平台上可能是8字节 } MyStruct; int main() { size_t size = sizeof(MyStruct); printf("Size of MyStruct is %zu bytes\n", size); void *ptr = malloc(size); if (ptr != NULL) { free(ptr); } return 0; } ``` 这段代码展示了定义了一个包含字符和整型成员的结构体,并请求了一块刚好容纳这样一个实例所需的堆空间。注意这里并没有显式指定任何特殊的对齐参数,默认情况下编译器会选择最优方案。 #### 常见问题及其解决方案 有时可能会遇到一些特殊情况需要手动干预才能达到预期效果: - 如果应用程序频繁创建大量小型对象而造成过多碎片化现象影响性能的话,可以通过自定义池管理技术或者选用更合适的第三方工具包解决问题。 - 当跨平台移植过程中发现原有设计不再适用当前环境所提供的硬件特性时,应该查阅目标架构文档了解具体要求并通过条件编译等方式灵活调整源码逻辑使之兼容多版本运行时状态[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值