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;
}

猜你喜欢

转载自www.cnblogs.com/sakurapiggy/p/13198072.html
今日推荐