1. C语言内存分配详解
C语言的内存分配方式从读取模式分为两种,一种时存储在RAM(可读可写)区的,另外一种时存储在ROM(只读)区。其中栈区,堆区,全部静态区都是RAM区,常量区和代码区是ROM区
-- --
-- 栈区 -- stack区:由编译器自动分配释放,存放局部变量,形参,返回值
-- --
--------------
-- --
-- 堆区 -- heap区:内存由程序员分配和释放,调用函数 malloc()和 free()
-- --
-------------- RAM
-- --
-- 全局静态区-- 未初始化全局/静态区
-- -- 已初始化全局/静态区
--------------
-- --
-- 常量区 -- 常量区,存放一些字符串,数字,const修饰的全局变量,内容不可被更改
-- --
-------------- ROM
-- --
-- 代码区 -- 代码区,字符串常量和define定义的常量有可能存放在代码区
-- --
下面以一个指针函数(返回值为一个指针类型的函数)来解释一下RAM区中的局部变量与全局变量的区别,有以下代码:
int* add(int a,int b) // 该函数返回一个指针类型的变量
{
int p = &(a+b);
return &p;
}
// 在主函数调用此指针函数
int main()
{
printf("%p",add(1,2)); // 打印地址查看返回的指针
return 0;
}
>>>>>>>> 0000000000000000 // 返回值为NULL,产生野指针
上述代码在运行过程中,由于 p为局部变量,存储在stack区,由在函数执行完成后由编译器自动释放,此时返回局部变量地址已经被释放,故产生野指针。如果将 p 设置为全局变量,代码如下
int p;
int* add(int a,int b)
{
p = (a+b); // p 为局部变量,函数调用完成后自动free
return &p;
}
int main()
{
printf("%d", *add(1,2));
return 0;
}
>>>>>>>>>> 3
此时p为全局变量,存放在全局静态区,内存占用将贯穿程序始终,此时将p的地址返回并解引用,运行之后程序正常,没有产生野指针。
2.sizeof 与 strlen 的区别
sizeof 是 C语言当中的一个运算符,用来计算占用内存的大小,同时也可以计算 int,float等数据类型的占用内存大小。它的计算过程在程序的编译器。
strlen 是 包含在 <string.h>头文件当中的一个函数,用于计算字符串的长度。计算过程在函数的运行期。
同时,strlen与sizeof在计算字符串大小时有区别:C语言中字符串的末尾有'\0'的结束符,strlen函数不会将'\0'的结束符计算进长度,而sizeof会将'\0'计算进占用内存的大小,因为字符串结束符也是占用内存的。
int main()
{
char a[] = "abc";
printf("%d\n", sizeof(a));
printf("%d", strlen(a));
return 0;
}
>>>>>>>> 4
>>>>>>>> 3