C语言学习笔记_内存数据和字符串
C语言学习笔记_内存数据和字符串
malloc和堆内存
// 堆内存需要手动申请,手动释放,一般用于大量内存的使用
// 申请的函数为malloc以及相关函数,释放函数为free
// malloc函数的返回值为void*,即返回一个指针,指向的数据类型可任意强制转换
// 在gcc中,malloc按照块分配,一块 为16Byte的内存
// 接下里的几个方式分配的内存大小均为16Byte
int* p1 = (int*)malloc(4);
int* p2 = (int*)malloc(0);
C语言的存放数据和代码的各个分段
代码段:可执行的函数存放于此,有些特殊数据会被放到代码段(即数据不可被修改):
// 这样申明的s会被存放之代码段,使得不可被修改,因此会导致段错误;
char* s = "linux";
*(s+0) = 'f';
// const定义的常量会被放到代码段,使得数据不可被修改
// 注意在gcc中不是如此,gcc不会放置代码段,因此gcc中可以绕过编译器使得数据可以修改
const int x = 10;
数据段:显示初始化为非零的全局变量和静态局部变量放在数据段;注意,普通的局部变量属于函数的数据,分配在栈内存中;
// 堆内存和数据段几乎拥有完全相同的属性,大部分时候是可以完全替换的,但是生命周期不一样
// 堆内存的生命周期从malloc开始,free结束;
// 而全局变量是从整个程序一开始就存在,程序回收才消失;
// 堆内存适用于程序的阶段性存在的变量,全局变量适用于程序一直存在的变量
// 堆内存的使用比全局变量广泛
bss段:未初始化或显示初始化为0的全局变量放在bss段;和数据段无本质区别,几乎可以不用明确区分;
字符串和字符数组的细节
// 定义一个数组s1,数组占6个字节,右值"linux"只存在于编译器中,初始化数组s1后即被丢弃;
// 本定义相当于char s1[] = {'l', 'i', 'n', 'u', 'x'};
// 若在函数内,则数组存在于栈内存中,数组可被更改;
char s1[] = "linux";
// 定义字符指针p,占4个字节,指针存在于栈内存中;
// 定义了字符串"linux",存在于代码段,内容不可被修改,代码段字符串的首地址赋值给了p;
char *s2 = "linux";
字符串存放在不同的位置:
#include <stdio.h>
#include <stdlib.h>
char a[7];
int main(void) {
char b[7] ;
// 字符串存在栈内存;
char *p1 = b;
// 字符串存在数据段;
char *p2 = a;
char *p2 = "linux";
// 字符串存在堆内存;
char *p3 = (char*)malloc(3*sizeof(char));
return 0;
}