登入帳戶  | 訂單查詢  | 購物車/收銀台(0) | 在線留言板  | 付款方式  | 運費計算  | 聯絡我們  | 幫助中心 |  加入書簽
會員登入   新用戶登記
HOME新書上架暢銷書架好書推介特價區會員書架精選月讀2023年度TOP分類瀏覽雜誌 臺灣用戶
品種:超過100萬種各類書籍/音像和精品,正品正價,放心網購,悭钱省心 服務:香港台灣澳門海外 送貨:速遞郵局服務站

新書上架簡體書 繁體書
暢銷書架簡體書 繁體書
好書推介簡體書 繁體書

11月出版:大陸書 台灣書
十月出版:大陸書 台灣書
九月出版:大陸書 台灣書
八月出版:大陸書 台灣書
七月出版:大陸書 台灣書
六月出版:大陸書 台灣書
五月出版:大陸書 台灣書
四月出版:大陸書 台灣書
三月出版:大陸書 台灣書
二月出版:大陸書 台灣書
一月出版:大陸書 台灣書
12月出版:大陸書 台灣書
11月出版:大陸書 台灣書
十月出版:大陸書 台灣書
九月出版:大陸書 台灣書

『簡體書』嵌入式C语言自我修养——从芯片、编译器到操作系统

書城自編碼: 3623162
分類:簡體書→大陸圖書→計算機/網絡程序設計
作者: 王利涛
國際書號(ISBN): 9787121408564
出版社: 电子工业出版社
出版日期: 2021-04-01

頁數/字數: /
書度/開本: 16开 釘裝: 平塑勒

售價:HK$ 147.5

我要買

share:

** 我創建的書架 **
未登入.


新書推薦:
不完美之美:日本茶陶的审美变
《 不完美之美:日本茶陶的审美变 》

售價:HK$ 87.4
现代化的迷途
《 现代化的迷途 》

售價:HK$ 98.6
钛经济
《 钛经济 》

售價:HK$ 77.3
甲骨文丛书·无垠之海:世界大洋人类史(全2册)
《 甲骨文丛书·无垠之海:世界大洋人类史(全2册) 》

售價:HK$ 322.6
中国救荒史
《 中国救荒史 》

售價:HK$ 109.8
三十六计绘本(共8册)走为上计+欲擒故纵+以逸待劳+无中生有+金蝉脱壳+浑水摸鱼+打草惊蛇+顺手牵羊 简装
《 三十六计绘本(共8册)走为上计+欲擒故纵+以逸待劳+无中生有+金蝉脱壳+浑水摸鱼+打草惊蛇+顺手牵羊 简装 》

售價:HK$ 177.4
茶之书(日本美学大师冈仓天心传世经典  诗意盎然地展现东方的智慧和美学 收录《卖茶翁茶器图》《茶具十二先生图》《煎茶图式》《历代名瓷图谱》等86幅精美茶室器物图)
《 茶之书(日本美学大师冈仓天心传世经典 诗意盎然地展现东方的智慧和美学 收录《卖茶翁茶器图》《茶具十二先生图》《煎茶图式》《历代名瓷图谱》等86幅精美茶室器物图) 》

售價:HK$ 65.0
云冈:人和石窟的1500年
《 云冈:人和石窟的1500年 》

售價:HK$ 72.8

 

建議一齊購買:

+

HK$ 178.2
《C Primer Plus 第6版 中文版》
+

HK$ 194.7
《C++ Primer Plus 第6版 中文版》
+

HK$ 148.8
《大话数据结构 溢彩加强版》
+

HK$ 104.3
《控制系统建模与仿真——基于MATLAB/Simulink的分》
+

HK$ 113.9
《嵌入式C语言技术实战开发(通过大量实战项目,帮助读者融会贯通》
+

HK$ 107.3
《剑指Offer:名企面试官精讲典型编程题(第2版)》
編輯推薦:
★ 多年嵌入式开发及培训一线实战经验倾囊分享
★ 内容几乎涵盖了嵌入式开发的所有知识点
★ 从底层到上层,从芯片、硬件到软件、框架
★ 大白话写作风格,通俗易懂,不怕学不会
★ 在ARM平台下讲解程序的编译、链接和运行原理
★ 现场“手撕”ARM汇编代码,剖析C函数调用、传参过程
★ 多角度剖析C:CPU/计算机体系结构/编译器/操作系统/软件工程
★ GNU C编译器扩展语法精讲(在GNU开源软件、Linux内核中)
★ 内存堆栈管理机制的底层剖析,从根源上理解内存错误
★ 从零开始一步一步搭建和迭代嵌入式软件框架
★ 教你用OOP思想分析Linux内核中复杂的驱动和子系统
★ C语言的多任务并发编程思想,CPU和操作系统零基础入门
★ 帮你快速构建嵌入式完整知识体系
★ 扩充AIoT时代嵌入式新的知识点
★ 更难能可贵的是,本书内容经过大量学员的验证
★ 学员说好才是真的好
內容簡介:
《嵌入式C语言自我修养:从芯片、编译器到操作系统》是一本专门为嵌入式读者打造的C语言进阶学习图书。本书的学习重点不再是C语言的基本语法,而是和嵌入式、C语言相关的一系列知识。作者以C语言为切入点,分别探讨了嵌入式开发所需要的诸多核心理论和技能,力图帮助读者从零搭建嵌入式开发所需要的完整知识体系和技能树。
《嵌入式C语言自我修养:从芯片、编译器到操作系统》从底层CPU的制造流程和工作原理开始讲起,到计算机体系结构,C程序的反汇编分析,程序的编译、运行和重定位,程序运行时的堆栈内存动态变化,GNU C编译器的扩展语法,指针的灵活使用,C语言的面向对象编程思想,C语言的模块化编程思想,C语言的多任务编程思想,进程、线程和协程的概念,从底层到上层,从芯片、硬件到软件、框架,几乎涵盖了嵌入式开发的所有知识点。
本书适合嵌入式学习者、开发者阅读学习,同样适合从事Linux下C语言开发工作的人员作为参考。阅读本书需要读者有一定的C语言基础,无论你是在校学生,还是需要充电学习的工程师,掌握了C语言的基本语法和编程技能后再阅读本书,学习效果会更佳。
關於作者:
王利涛
嵌入式工程师、培训讲师,多年嵌入式开发经验,包括芯片测试、BSP、驱动开发、USB子系统等。目前在开发《嵌入式工程师自我修养》系列在线视频教程,以及在个人博客(www.zhaixue.cc)分享更多的嵌入式、Linux、AIoT技术。
目錄
第1章工欲善其事,必先利其器
1.1 代码编辑工具:Vim
1.1.1 安装Vim
1.1.2 Vim常用命令
1.1.3 Vim配置文件:vimrc
1.1.4 Vim的按键映射
1.2 程序编译工具:make
1.2.1 使用IDE编译C程序
1.2.2 使用gcc编译C源程序
1.2.3 使用make编译程序
1.3 代码管理工具:Git
1.3.1 什么是版本控制系统
1.3.2 Git的安装和配置
1.3.3 Git常用命令
第2章计算机体系结构与CPU工作原理
2.1 一颗芯片是怎样诞生的
2.1.1 从沙子到单晶硅
2.1.2 PN结的工作原理
2.1.3 从PN结到芯片电路
2.1.4 芯片的封装
2.2 一颗CPU是怎么设计出来的
2.2.1 计算机理论基石:图灵机
2.2.2 CPU内部结构及工作原理
2.2.3 CPU设计流程
2.3 计算机体系结构
2.3.1 冯·诺依曼架构
2.3.2 哈弗架构
2.3.3 混合架构
2.4 CPU性能提升:Cache机制
2.4.1 Cache的工作原理
2.4.2 一级Cache和二级Cache
2.4.3 为什么有些处理器没有Cache
2.5 CPU性能提升:流水线
2.5.1 流水线工作原理
2.5.2 超流水线技术
2.5.3 流水线冒险
2.5.4 分支预测
2.5.5 乱序执行
2.5.6 SIMD和NEON
2.5.7 单发射和多发射
2.6 多核CPU
2.6.1 单核处理器的瓶颈
2.6.2 片上多核互连技术
2.6.3 big.LITTLE结构
2.6.4 超线程技术
2.6.5 CPU核数越多越好吗
2.7 后摩尔时代:异构计算的崛起
2.7.1 什么是异构计算
2.7.2 GPU
2.7.3 DSP
2.7.4 FPGA
2.7.5 TPU
2.7.6 NPU
2.7.7 后摩尔时代的XPU们
2.8 总线与地址
2.8.1 地址的本质
2.8.2 总线的概念
2.8.3 总线编址方式
2.9 指令集与微架构
2.9.1 什么是指令集
2.9.2 什么是微架构
2.9.3 指令助记符:汇编语言
第3章ARM体系结构与汇编语言
3.1 ARM体系结构
3.2 ARM汇编指令
3.2.1 存储访问指令
3.2.2 数据传送指令
3.2.3 算术逻辑运算指令
3.2.4 操作数:operand2详解
3.2.5 比较指令
3.2.6 条件执行指令
3.2.7 跳转指令
3.3 ARM寻址方式
3.3.1 寄存器寻址
3.3.2 立即数寻址
3.3.3 寄存器偏移寻址
3.3.4 寄存器间接寻址
3.3.5 基址寻址
3.3.6 多寄存器寻址
3.3.7 相对寻址
3.4 ARM伪指令
3.4.1 LDR伪指令
3.4.2 ADR伪指令
3.5 ARM汇编程序设计
3.5.1 ARM汇编程序格式
3.5.2 符号与标号
3.5.3 伪操作
3.6 C语言和汇编语言混合编程
3.6.1 ATPCS规则
3.6.2 在C程序中内嵌汇编代码
3.6.3 在汇编程序中调用C程序
3.7 GNU ARM汇编语言
3.7.1 重新认识编译器
3.7.2 GNU ARM编译器的伪操作
3.7.3 GNU ARM汇编语言中的标号
3.7.4 .section伪操作
3.7.5 基本数据格式
3.7.6 数据定义
3.7.7 汇编代码分析实战
第4章程序的编译、链接、安装和运行
4.1 从源程序到二进制文件
4.2 预处理过程
4.3 程序的编译
4.3.1 从C文件到汇编文件
4.3.2 汇编过程
4.3.3 符号表与重定位表
4.4 链接过程
4.4.1 分段组装
4.4.2 符号决议
4.4.3 重定位
4.5 程序的安装
4.5.1 程序安装的本质
4.5.2 在Linux下制作软件安装包
4.5.3 使用apt-get在线安装软件
4.5.4 在Windows下制作软件安装包
4.6 程序的运行
4.6.1 操作系统环境下的程序运行
4.6.2 裸机环境下的程序运行
4.6.3 程序入口main()函数分析
4.6.4 BSS段的小秘密
4.7 链接静态库
4.8 动态链接
4.8.1 与地址无关的代码
4.8.2 全局偏移表
4.8.3 延迟绑定
4.8.4 共享库
4.9 插件的工作原理
4.10 Linux内核模块运行机制
4.11 Linux内核编译和启动分析
4.12 U-boot重定位分析
4.13 常用的binutils工具集
第5章内存堆栈管理
5.1 程序运行的“马甲”:进程
5.2 Linux环境下的内存管理
5.3 栈的管理
5.3.1 栈的初始化
5.3.2 函数调用
5.3.3 参数传递
5.3.4 形参与实参
5.3.5 栈与作用域
5.3.6 栈溢出攻击原理
5.4 堆内存管理
5.4.1 裸机环境下的堆内存管理
5.4.2 uC/OS的堆内存管理
5.4.3 Linux堆内存管理
5.4.4 堆内存测试程序
5.4.5 实现自己的堆管理器
5.5 mmap映射区域探秘
5.5.1 将文件映射到内存
5.5.2 mmap映射实现机制分析
5.5.3 把设备映射到内存
5.5.4 多进程共享动态库
5.6 内存泄漏与防范
5.6.1 一个内存泄漏的例子
5.6.2 预防内存泄漏
5.6.3 内存泄漏检测:MTrace
5.6.4 广义上的内存泄漏
5.7 常见的内存错误及检测
5.7.1 总有一个Bug,让你泪流满面
5.7.2 使用core dump调试段错误
5.7.3 什么是内存踩踏
5.7.4 内存踩踏监测:mprotect
5.7.5 内存检测神器:Valgrind
第6章GNU C编译器扩展语法精讲
6.1 C语言标准和编译器
6.1.1 什么是C语言标准
6.1.2 C语言标准的内容
6.1.3 C语言标准的发展过程
6.1.4 编译器对C语言标准的支持
6.1.5 编译器对C语言标准的扩展
6.2 指定初始化
6.2.1 指定初始化数组元素
6.2.2 指定初始化结构体成员
6.2.3 Linux内核驱动注册
6.2.4 指定初始化的好处
6.3 宏构造“利器”:语句表达式
6.3.1 表达式、语句和代码块
6.3.2 语句表达式
6.3.3 在宏定义中使用语句表达式
6.3.4 内核中的语句表达式
6.4 typeof与container_of宏
6.4.1 typeof关键字
6.4.2 typeof使用示例
6.4.3 Linux内核中的container_of宏
6.4.4 container_of宏实现分析
6.5 零长度数组
6.5.1 什么是零长度数组
6.5.2 零长度数组使用示例
6.5.3 内核中的零长度数组
6.5.4 思考:指针与零长度数组
6.6 属性声明:section
6.6.1 GNU C编译器扩展关键字:__attribute__
6.6.2 属性声明:section
6.6.3 U-boot镜像自复制分析
6.7 属性声明:aligned
6.7.1 地址对齐:aligned
6.7.2 结构体的对齐
6.7.3 思考:编译器一定会按照aligned指定的方式对齐吗
6.7.4 属性声明:packed
6.7.5 内核中的aligned、packed声明
6.8 属性声明:format
6.8.1 变参函数的格式检查
6.8.2 变参函数的设计与实现
6.8.3 实现自己的日志打印函数
6.9 属性声明:weak
6.9.1 强符号和弱符号
6.9.2 函数的强符号与弱符号
6.9.3 弱符号的用途
6.9.4 属性声明:alias
6.10 内联函数
6.10.1 属性声明:noinline
6.10.2 什么是内联函数
6.10.3 内联函数与宏
6.10.4 编译器对内联函数的处理
6.10.5 思考:内联函数为什么定义在头文件中
6.11 内建函数
6.11.1 什么是内建函数
6.11.2 常用的内建函数
6.11.3 C标准库的内建函数
6.11.4 内建函数:__builtin_constant_p(n)
6.11.5 内建函数:__builtin_expect(exp,c)
6.11.6 Linux内核中的likely和unlikely
6.12 可变参数宏
6.12.1 什么是可变参数宏
6.12.2 继续改进我们的宏
6.12.3 可变参数宏的另一种写法
6.12.4 内核中的可变参数宏
第7章数据存储与指针
7.1 数据类型与存储
7.1.1 大端模式与小端模式
7.1.2 有符号数和无符号数
7.1.3 数据溢出
7.1.4 数据类型转换
7.2 数据对齐
7.2.1 为什么要数据对齐
7.2.2 结构体对齐
7.2.3 联合体对齐
7.3 数据的可移植性
7.4 Linux内核中的size_t类型
7.5 为什么很多人编程时喜欢用typedef
7.5.1 typedef的基本用法
7.5.2 使用typedef的优势
7.5.3 使用typedef需要注意的地方
7.5.4 typedef的作用域
7.5.5 如何避免typedef被大量滥用
7.6 枚举类型
7.6.1 使用枚举的三种方法
7.6.2 枚举的本质
7.6.3 Linux内核中的枚举类型
7.6.4 使用枚举需要注意的地方
7.7 常量和变量
7.7.1 变量的本质
7.7.2 常量存储
7.7.3 常量折叠
7.8 从变量到指针
7.8.1 指针的本质
7.8.2 一些复杂的指针声明
7.8.3 指针类型与运算
7.9 指针与数组的“暧昧”关系
7.9.1 下标运算符[]
7.9.2 数组名的本质
7.9.3 指针数组与数组指针
7.10 指针与结构体
7.11 二级指针
7.11.1 修改指针变量的值
7.11.2 二维指针和指针数组
7.11.3 二级指针和二维数组
7.12 函数指针
7.13 重新认识void
第8章C语言的面向对象编程思想
8.1 代码复用与分层思想
8.2 面向对象编程基础
8.2.1 什么是OOP
8.2.2 类的封装与实例化
8.2.3 继承与多态
8.2.4 虚函数与纯虚函数
8.3 Linux内核中的OOP思想:封装
8.3.1 类的C语言模拟实现
8.3.2 链表的抽象与封装
8.3.3 设备管理模型
8.3.4 总线设备模型
8.4 Linux内核中的OOP思想:继承
8.4.1 继承与私有指针
8.4.2 继承与抽象类
8.4.3 继承与接口
8.5 Linux内核中的OOP思想:多态
第9章C语言的模块化编程思想
9.1 模块的编译和链接
9.2 系统模块划分
9.2.1 模块划分方法
9.2.2 面向对象编程的思维陷阱
9.2.3 规划合理的目录结构
9.3 一个模块的封装
9.4 头文件深度剖析
9.4.1 基本概念
9.4.2 隐式声明
9.4.3 变量的声明与定义
9.4.4 如何区分定义和声明
9.4.5 前向引用和前向声明
9.4.6 定义与声明的一致性
9.4.7 头文件路径
9.4.8 Linux内核中的头文件
9.4.9 头文件中的内联函数
9.5 模块设计原则
9.6 被误解的关键字:goto
9.7 模块间通信
9.7.1 全局变量
9.7.2 回调函数
9.7.3 异步通信
9.8 模块设计进阶
9.8.1 跨平台设计
9.8.2 框架
9.9 AIoT时代的模块化编程
第10章C语言的多任务编程思想和操作系统入门
10.1 多任务的裸机实现
10.1.1 多任务的模拟实现
10.1.2 改变任务的执行频率
10.1.3 改变任务的执行时间
10.2 操作系统基本原理
10.2.1 调度器工作原理
10.2.2 函数栈与进程栈
10.2.3 可重入函数
10.2.4 临界区与临界资源
10.3 中断
10.3.1 中断处理流程
10.3.2 进程栈与中断栈
10.3.3 中断函数的实现
10.4 系统调用
10.4.1 操作系统的API
10.4.2 操作系统的权限管理
10.4.3 CPU的特权模式
10.4.4 Linux系统调用接口
10.5 揭开文件系统的神秘面纱
10.5.1 什么是文件系统
10.5.2 文件系统的挂载
10.5.3 根文件系统
10.6 存储器接口与映射
10.6.1 存储器与接口
10.6.2 存储映射
10.6.3 嵌入式启动方式
10.7 内存与外部设备
10.7.1 内存与外存
10.7.2 外部设备
10.7.3 I/O端口与I/O内存
10.8 寄存器操作
10.8.1 位运算应用
10.8.2 操作寄存器
10.8.3 位域
10.9 内存管理单元MMU
10.9.1 地址转换
10.9.2 权限管理
10.10 进程、线程和协程
10.10.1 进程
10.10.2 线程
10.10.3 线程池
10.10.4 协程
10.10.5 小结
內容試閱
你要学习的,不仅仅是C语言……
对于上面的几个C语言测试,如果你已经知道了答案,并且知道其要考查的是什么知识点,恭喜你,你对C语言及计算机体系结构的知识已经很熟悉了。如果回答得不是很好,偷偷用百度也没有搜到理想的答案,也不用气馁,因为这次测试要考查的内容其实已经不仅仅是C语言的知识了,而是和嵌入式C语言开发相关的一些理论知识,如处理器架构、操作系统、编译原理、编译器特性、内存堆栈管理、Linux内核中的GNU C扩展语法等。
当然,上面的测试也不是为了故意扎你心或者卖关子,让你赶紧掏腰包买下这本书,而是想要传递一个信息:要想从事嵌入式开发工作,尤其是嵌入式Linux内核驱动开发工作,你要精通的不仅仅是C语言,好还要掌握和C语言相关的一系列基础理论和调试技能。笔者也是过来人,从初学习嵌入式到从事嵌入式开发工作,这一路走来坎坷崎岖,什么都不说了,说多了都是泪。从一开始连指针都不会用、不敢用,看内核驱动代码一头雾水,越看越没底、越看越没自信,到现在不再犯怵,有自信和能力看懂内核中的代码细节和系统框架,这种进步不是天上掉下来的,也不是一不小心跌入山洞,捡到武功秘籍练出来的,而是不断地学习和实践、反复迭代、不断完善自己的知识体系和技能树,才慢慢达到的。学习没有捷径可走,要想真正学好嵌入式、精通嵌入式,个人觉得除了精通C语言,好还要具备以下完整的知识体系和编程技能。
l 半导体基础、CPU工作原理、硬件电路、计算机系统结构。
l ARM体系结构与汇编指令、汇编程序设计、ARM反汇编分析。
l 程序的编译、链接、安装、运行和重定位分析。
l 熟悉C语言标准、ARM、GNU编译器的特性和扩展语法。
l C语言的模块化编程思想,学会使用模块化思想去分析复杂的系统。
l C语言的面向对象编程(简称OOP)思想,学会使用OOP思想去分析Linux内核驱动。
l 对指针的深刻理解,对复杂指针的声明和灵活应用。
l 对内存堆栈管理、内存泄漏、栈溢出、段错误的深刻理解。
l 多任务并发编程思想,CPU和操作系统基础理论。
本书内容及写作初衷
本书从C语言的角度出发,分10章,在默认读者已经掌握C语言基本语法的基础上,和大家一起探讨、学习C语言背后的CPU工作原理、计算机体系结构、ARM平台下程序的编译/链接、程序运行时的内存堆栈管理等底层知识。同时,针对嵌入式开发领域,用3章分别探讨了C语言的面向对象编程思想、模块化编程思想和多任务编程思想,这些底层知识和编程思想构成了嵌入式开发所需要的通用理论基础和核心技能。尤其是对于很多从不同专业转行到嵌入式开发的朋友,由于专业背景的差异,导致每个人的知识储备和编程技能树参差不齐,在学习嵌入式开发的过程中会经常遇到各种各样的问题,陷入学习的困境。
本书的写作初衷就是为不同专业背景的读者搭建嵌入式开发所需要的完整知识体系和认知框架。掌握了这些基础理论和编程技能,也就补齐了短板,可为后续的嵌入式开发进阶学习打下坚实的基础。
本书特色
l 大白话写作风格,通俗易懂,不怕学不会,就怕你不学。
l 大量的配图、原理图,图文并茂,更加有利于学习和理解。
l 在ARM平台下讲解程序的编译、链接和运行原理(独创)。
l 现场“手撕”ARM汇编代码,从反汇编角度剖析C函数调用、传参过程。
l 多角度剖析C语言:CPU、计算机体系结构、编译器、操作系统、软件工程。
l GNU C编译器扩展语法精讲(在GNU开源软件、Linux内核中大量使用)。
l 内存堆栈管理机制的底层剖析,从根源上理解内存错误。
l 从零开始一步一步搭建和迭代嵌入式软件框架。
l 教你用OOP思想分析Linux内核中复杂的驱动和子系统。
l C语言的多任务并发编程思想,CPU和操作系统零基础入门。
读者定位
本书针对的是嵌入式开发,尤其是嵌入式Linux开发背景下的C语言进阶学习,比较适合在校学生、嵌入式学员、工作1~3年的职场新兵阅读和学习。为了达到更好的学习效果,在阅读本书之前,首先要确保你已经掌握了C语言的基本语法,并且至少使用过一款C语言集成开发环境(VC 6.0、Visual Studio、C-Free、GCC都可以),开发过一个完整的C语言项目(课程设计也算)。有了这些基础和编程经验之后,学习效果会更好。

5.7.1 总有一个Bug,让你泪流满面
总有一种兴奋让你不能自抑,花枝乱颤;总有一个Bug让你夙夜难眠,泪流满面。当一个Bug让你毫无头绪,让你调到天昏地暗,到后几乎要放弃,开始漫无目的地乱改代码,祈求奇迹出现时,说明你需要休息一下了:出去转一转,吹个风,说不定灵感乍现,一下子又有了思路……
发生段错误的根本原因在于非法访问内存,即访问了权限未许可的内存空间。在日常编程中,有哪些行为会引发段错误呢?
常见的错误行为是访问内存禁区。如前面的图5-47所示的内核空间、零地址、堆和mmap区域之间的内存空间,这部分地址空间要么被内核占用,要么还处于“未开发”状态,需要申请才能使用。这就和城郊的荒地一样,你不能一看空着就跑过来盖房子,你需要先获得土地的使用权。
int main (void)
{
int i;
i = *(int *)0x8048000; //代码段只能读,不能写
*(int *)0x8048000 = 100; //段错误
i = *(int *)0x0; //段错误
return 0;
}

当我们往一个只读区域的地址空间执行写操作时,或者访问一个禁止访问的地址(如零地址)时,都会发生段错误。在实际编程中,总会因为各种各样的疏忽不小心触碰到这些“红线”,导致段错误。
#include
int main (void)
{
char *p;
*p = 1;
return 0;
}

编译运行上面的程序,可能正常运行,也可能会发生段错误。在函数内定义的局部变量如果未初始化,它的值是随机的,如果你人品大爆发,这个地址处于安全访问区,则向这个地址写数据是没有大问题的,至少不会报段错误。如果你运气不好,这个随机值正好处在内核空间,你再向这个地址写数据,则程序会立刻发生段错误并终止运行。
在我们调试链表时,通常通过指针来操作每一个节点。如果指针在遍历链表时已经指向链表的末尾或头部,指针已经指向NULL了,此时再通过该指针去访问节点的成员,就相当于访问零地址了,也会发生一个段错误,这个指针也就变成了非法指针。
在Linux环境下,每一个用户进程默认有8MB大小的栈空间,如果你在函数内定义大容量的数组或局部变量,就可能造成栈溢出,也会引发一个段错误。内核中的线程也是如此,每一个内核线程只有8KB的内核栈,在实际使用中也要非常小心,防止堆栈溢出。
在访问数组时,如果超越数组的边界继续访问,也会发生一个段错误。我们使用malloc()申请的堆内存,如果不小心多次使用free()进行释放,通常也会触发一个段错误。
//double_free.c
#include
int main (void)
{
char *p;
p = (char *) malloc (64);
free(p);
free(p); //引发段错误
return 0;
}

程序在编译阶段出现错误,我们可以通过错误提示信息很快定位并解决。由于C语言语法检查的宽松性,程序中对内存访问的各种操作并不报错,或者给一个警告信息,这会导致程序在运行期间出现段错误时很难定位。此时我们可以借助一些第三方工具来快速定位段错误。

 

 

書城介紹  | 合作申請 | 索要書目  | 新手入門 | 聯絡方式  | 幫助中心 | 找書說明  | 送貨方式 | 付款方式 香港用户  | 台灣用户 | 海外用户
megBook.com.hk
Copyright © 2013 - 2024 (香港)大書城有限公司  All Rights Reserved.