linux c 指针和内存分配内存,Linux C语言指针与内存学习笔记
8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
环境准备
Ubuntu 操作系统、VIM 编辑器、GCC 编译器、GDB调试器。
初始指针
通过两个数的交换引入指针指针的概念。
swap(int a, int b);
swap(a, b);
swap(int *a, int *b);
swap(&a, &b);
gdb 调试工具的使用
分析原理、分析结果。
使用 gdb -help 检查电脑是否安装。
源程序用于调试:gcc -g main.c -o main.out
使用 gdb 调试:gdb ./main.out
gdb 一些常用命令:l :列出当前软件项目源代码
enter:继续执行上一条命令
break 12:断点打在 12 行
start:开始调试,默认断点在 main 函数的入口处
p a:打印变量 a 的值
n:执行下一行
s:进入一个函数的内部
bt:查看函数堆栈
f 1:切换函数栈
q:退出调试
指针与内存
计算机中的数据表示方法:
计算用二进制,显示为十进制,编程用十六进制。
内存管理:
内存是什么?内存是由操作系统统一管理。
1 Byte= 8 Bits
插两根 2G 内存条 <=> 插一根 4G 内存条,计算机中操作系统把内存看成是一个整体来计算内存的大小。
内存条不是你想插多少就插多少的,32 bit 的操作系统最大使用 4G 内存。32 位计算机的地址总线是 32 位的,也就是寻址空间是 32 位。
32 位指的是:给内存编号只能编到 32 个二进制位。
地址总线可以存在多种状态,32 根总线就有 2^32 个状态。2^32 B = 4GB 。 4G 的内存是远远不够用的,所以现在 64 位的操作系统更为流行。操作系统会对所有的内存进行编号,每个编号对应唯一的内存字节地址。
内存都要交给操作系统来管理。一个计算机中可能同时要运行多个程序, 要由程序员来对内存直接进行管理是不太合理的,内存的占用不稳定。 内存之中有一个部分内存空间是给操作系统内核使用的,操作系统内存和用户内存隔离开的好处:操作系统的内存不会被大量占用
避免机器卡住、卡死、死机等状态
可通过操作系统把应用程序关闭
使操作系统更安全
C 语言代码被编译之后存到磁盘,运行时编译后的二进制数据加载到内存中,代码段。声明一些全局变量或者声明一些变量,这些通常放在数据段。
C 程序在内存中布局文本(代码)段
初始化数据段
未初始化(bbs)数据段
堆
栈
文本或代码段:Text or Code Segment
也叫做代码段。顾名思义,该段存储包含已编译程序的机器代码,通常是只读段,用于防止程序被意外修改。
初始化数据段:Initialized Data Segment
初始化数据存储预先初始化的所有 global, ` static,const和外部变量(extern` 关键字声明)。
还会因为 const 而细分为可读可写区域和只读区域。
#include
char str1[] = "Hello"; // 全局变量存储在数据段的可读可写区域const char str2[] = "World"; // 存储在数据段的只读区域
int main()
{
static int a = 0; // 静态变量存储在数据段 return 0;
}
未初始化数据段:Uninitialized Data Segment (bss)
#include
char c; // 未初始化变量存储在未初始化数据段
int main()
{
static int i; // 未初始化静态变量存储在未初始化数据段 return 0;
}
通常,初始化数据段和未初始化数据段统称为数据段。
堆
堆是通常发生动态内存分配的段。在 C/C++ 中,当需要使用 malloc / calloc / new 函数分配更多内存时,堆会向上增长。
#include int main()
{
char *p=(char*)malloc(sizeof(char)); // 内存分配在堆段 return 0;
}
栈
栈段用于存储所有局部变量,用于将参数传递给函数以及函数调用结束后要执行的指令的返回地址。局部变量具有定义它们的所在函数块的范围,它们是在控制进入所在函数块时创建的。所有递归函数调用都添加到内存的栈中。
变量和指针的本质:C 语言语法是不允许我们直接操作代码段的。
变量的本质是什么?变量名它只是一个代号
变量的本质就是内存
int *pa = &a;
(gdb)p pa与 p &a 得到的结果相等
(gdb)p &pa打印 pa 的这个变量自己的地址
C 语言中所有的变量都有类型:int 类型就保存整数
double 类型就保存双精度的浮点数
那么指针保存的是什么呢?指针保存的就是内存地址
操作系统对内存的管理
32 bit :指针是 4 Byte
64 bit:指针是 8 Byte
代码段是由低地址向高地址分配的,先声明的函数地址小,后声明的函数地址大。而栈刚好相反,
函数栈以及数据段内存
静态变量在数据段里面的一个固定的位置。
函数指针与指针指向的数据访问
函数指针的声明语法。
char (*pf)(int);
// pf指向一个函数。*pf是一个函数指针
// char是函数的返回值
// int是参数的类型
字符串和数组
数组申明的内存排列
*(p + i) 等同于 p[i]
gcc 编译器的自动优化,会把同一类型的变量放在一起。
指针运算
++ 先判断数据的类型,然后再往下移,如 int 类型,则移 4 个字节。
int array[3];
int *pa = array;
pa 是一个可以指向不同地址的指针变量。
array 本质上是一个指针常量。
指针常量能做的事情,指针变量是一定可以做的,但是反过来就不行。
数组和指针有一定的相同点,已有一定的差别。
字符数组和指针字符串
#include
int main()
{
char str[] = "hello";
char *str2 = "world";
char str3[10];
printf("input the valuen");
scanf("%s", str3);
printf("str is %sn", str);
printf("str2 is %sn", str2);
printf("str3 is %sn", str3);
return 0;
}
// ➜ Desktop ./a.out
// input the value
// hello
// str is hello
// str2 is world
// str3 is hello
str2 在代码段,是不可以再进行写入操作的。栈内存和堆内存都是可以被写入的。
linux c 指针和内存分配内存,Linux C语言指针与内存学习笔记相关推荐
- Cocos2d-x 3.x:如何进行合理的内存分配(使用AutoreleasePool 来合理的管理内存)
Cocos2d-x 3.x:如何进行合理的内存分配(使用AutoreleasePool 来合理的管理内存) 本文转载至深入理解Cocos2d-x 3.x:如何进行合理的内存分配 设想如下场景,这是一个 ...
- brk函数 linux,brk和sbrk及内存分配函数相关-linux+内存
brk和sbrk主要的工作是实现虚拟内存到内存的映射.在GNUC中,内存分配是这样的: 每个进程可访问的虚拟内存空间为3G,但在程序编译时,不可能也没必要为程序分配这么大的空间,只分配并不大的数据段空 ...
- linux内存分配机制,Linux内存分配机制:SLAB / SLUB / SLOB
Linux内存分配机制:SLAB / SLUB / SLOB [日期:2011-07-15] 来源:Linux社区 作者:do2jiang [字体:大 中 小] slob: introduce the ...
- linux内存分配缺陷,Linux系统优化-内存错误分析
造成内存错误的样例分析 例一:(释放代码段空间导致内存错误) 图1 Coding 运行错误显示: 图2内存错误显示 分析:如图2所示运行后出现内存错误,free(): invalid pointer ...
- 不允许指针指向不完整的类类型_8.7 C语言动态内存分配与指向它的指针变量
01什么是内存的动态分配 1.全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,这个存储区是一个"栈"的区域. 2.C语言允许建立内存 ...
- 面试准备每日五题:C++(三)——全局局部变量、内存分配、strcpysprintfmemcpy、函数指针、引用
文章目录 1. 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的? 2. 简述C.C++程序编译的内存分配情况 3. 简述strcpy.sprintf 与memcpy 的区别 ...
- c语言关于内存笔试,4、C语言面试笔试--内存操作-指针
文章目录1.指针变量1.1 基本概念1.2 指针运算1.3 面试题2. 常量和常量指针2.1 字面常量和符号常量2.2 const指针常量2.2.1 常量指针2.2.2 常量指针变量2.2.3 指针常 ...
- c语言内存分配与释放 不同类别变量的内存分配和释放的区别
1.不同变量使用内存的区别 静态存储类别的变量:内存数量在编译时确定,程序开始执行时创建,程序结束时销毁.(static.const) 自动存储类别的变量:程序进入变量定义所在块时存在,离开块时销毁. ...
- go list指针_「GCTT 出品」Go 语言机制之内存剖析
前序(Prelude) 本系列文章总共四篇,主要帮助大家理解 Go 语言中一些语法结构和其背后的设计原则,包括指针.栈.堆.逃逸分析和值/指针传递.这是第三篇,主要介绍堆和逃逸分析.(译者注:这一篇可 ...
- CUDA内存分配、释放、传输,固定内存
/** 内存分配* if failed, return cudaErrorMemoryAllocation */cudaError_t cudaMalloc(void **devPtr, size_t ...
最新文章
- 11岁少女叫板支付宝!会写代码的孩子,到底多可怕?
- 计算机网络分类(按覆盖范围分类)“名称、范围”
- mysql提取数据字符_如何从MySQL查询的字符串中提取数值?
- 铁大Facebook——电梯演讲
- 英语作文万能句子总结版
- 分成收益破5000后,我决定将付费专栏开源了
- 传统公司部署OpenStack(t版)简易介绍(七)——cinder模块部署
- 七个帮助你处理Web页面层布局的jQuery插件
- 【BZOJ4521】手机号码,数位dp
- UVA10934 Dropping water balloons【DP】
- python窗口大小动态变化_python – 如何让tkinter画布动态调整窗口宽度?
- 网络地址16777343是什么地址?
- [译文]使用VBA-SDL-H寻找图片
- 迅捷pdf转换器在线转换——六大转换
- 阿里云ECS和WorldPress + Nginx实现固定连接策略
- 学习React Native必看的几个开源项目
- java 日志门面_slf4j-日志门面担当
- PHP 实现 apple 苹果快捷登录
- 感觉编程还是需要逐渐熟练的技术工种吧,分几个维度来描述。
- Vendor NDK