文章分类 -  C/C++编程

摘要:malloc()是C语言中动态存储管理的一组标准库函数之一。其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针malloc()工作机制malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块 阅读全文
posted @ 2012-10-18 10:28 Mr.Rico 阅读(454) 评论(0) 推荐(1) 编辑
摘要:这篇文章主要讲解G++编译器中虚继承的对象内存分布问题,从中也引出了dynamic_cast和static_cast本质区别、虚函数表的格式等一些大部分C++程序员都似是而非的概念。问题拿捏得十分到位,下面是我对原文的翻译,原文见这里(By Edsko de Vries, January 2006)。本文是介绍C++的技术文章,假定读者对于C++有比较深入的认识,同时也需要一些汇编知识。本文我们将阐释GCC编译器针对多重继承和虚拟继承下的对象内存布局。尽管在理想的使用环境中,一个C++程序员并不需要了解这些编译器内部实现细节,实际上,编译器针对多重继承(特别是虚拟继承)的各种实现细节对于我们编 阅读全文
posted @ 2012-10-18 08:09 Mr.Rico 阅读(446) 评论(0) 推荐(0) 编辑
摘要:大多数时候,我们研究的是如何阅读源代码。但在一些情况下,比如源代码不公开或得到源代码的代价很高的情况下,我们又不得不需要了解程序的行为,这 时阅读二进制文件就非常重要。假设现在有一个二进制可执行文件,我们木有源代码,但要了解它的实现,这里仅简单列出一些常用的工具。 阅读方式可分为两个方面:静态阅读和动态阅读。 静态阅读 首先,file命令可以查看可执行文件的大体信息。比如是哪种格式的,哪个体系结构的,有没有调试信息等。这些决定了需要用哪个版本的工具进行进一 步查看。比如如果是arm体系的可执行文件就可用arm toolchain里的工具,如arm-eabi-objdump,arm-eab... 阅读全文
posted @ 2012-08-27 23:10 Mr.Rico 阅读(1965) 评论(0) 推荐(0) 编辑
摘要:"该死系统存在内存泄漏问题",项目中由于各方面因素,总是有人抱怨存在内存泄漏,系统 长时间运行之后,可用内存越来越少,甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一,因为除非用完内存或调用malloc失败,否则都不会导 致任何问题。实际上,使用C/C++这类没有垃圾回收机制的语言时,你很多时间都花在处理如何正确释放内存上。如果程序运行时间足够长,如后台进程运行在 服务器上,只要服务器不宕机就一直运行,一个小小的失误也会对程序造成重大的影响,如造成某些关键服务失败。对于内存泄漏,本人深有体会!实习的时候,公司一个项目中就存在内存泄漏问题,项目的代码两非常大,后台进程 阅读全文
posted @ 2012-08-27 09:47 Mr.Rico 阅读(474) 评论(0) 推荐(0) 编辑
摘要:为什么需要知道C/C++的内存布局和在哪可以可以找到想要的数据?知道内存布局对调试程序非常有帮助,可以知道程序执行时,到底做了什么,有助于写出干净的代码。本文的主要内容如下:源文件转换为可执行文件可执行程序组成及内存布局数据存储类别一个实例总结源文件转换为可执行文件源文件经过以下几步生成可执行文件:1、预处理(preprocessor):对#include、#define、#ifdef/#endif、#ifndef/#endif等进行处理 2、编译(compiler):将源码编译为汇编代码 3、汇编(assembler):将汇编代码汇编为目标代码 4、链接(linker):将目标代码链接为可执 阅读全文
posted @ 2012-08-27 09:29 Mr.Rico 阅读(577) 评论(0) 推荐(0) 编辑
摘要:本文首先向读者讲解了Linux下进程地址空间的布局以及进程堆栈帧的结构,然后在此基础上介绍了Linux下缓冲区溢出攻击的原理及对策。 前言 从 逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用。当函数调用发生时,新的堆栈帧被压入堆栈;当函数返回时,相应的堆栈帧从堆 栈中弹出。尽管堆栈帧结构的引入为在高级语言中实现函数或过程这样的概念提供了直接的硬件支持,但是由于将函数返回地址这样的重要数据保存在程序员可见的 堆栈中,因此也给系统安全带来了极大的隐患。 历史上最著名的缓冲区溢出攻击可能要算是1988年11月2日的Morris Worm所携带的攻击代... 阅读全文
posted @ 2012-07-22 19:07 Mr.Rico 阅读(3431) 评论(0) 推荐(0) 编辑
摘要:每年的 09/28 於我都是一个特殊的日子 -- 不只是因为教师节。今年很特殊地没有普天同庆,那麽我就写篇文章自己庆祝一下好了。我於今年七月发表了一本着作《多型与虚拟》和一本译作《深度探索C++物件模型》,获得很大的回响。这些作品都不是针对 C++ 的完全初学者所写,但从初阶到高阶为数众多的 C++ guy,热情地表达了他们对这些主题的喜悦。在许多来信中,我看到一些有趣的现象,也感受到一些值得整理下来的想法。所以,根据我个人的学习过往、我的教学经验、以及周遭朋友的心得交流,写下这篇文章,或可为後学者戒。●《多型与虚拟》序言节录首先让我节录《多型与虚拟》一书序言:《多型与虚拟》序 节录(侯俊杰. 阅读全文
posted @ 2012-07-16 15:18 Mr.Rico 阅读(495) 评论(0) 推荐(0) 编辑
摘要:在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bjarne Stroustrup, 该门语言则命名为——C with classes,四年后改称为C++。C++是一门通用编程语言,支持多种编程范式,包括过程式、面向对象(object-oriented programming, OP)、泛型(generic programming, GP),后来为泛型而设计的模版,被发现及证明是图灵完备的,因此使C++亦可支持模版元编程范式(template metaprogramming, TMP)。C++继承了C的特色,既为高级语言,又含低级.. 阅读全文
posted @ 2012-07-16 14:55 Mr.Rico 阅读(927) 评论(0) 推荐(1) 编辑
摘要:缘起 在项目中发现某些情况下,对象的析构函数不被调用,比如程序调用exit(), 异常终止等。那么,析构函数什么情况下不会被调用呢? RAII RAII(资源获取即初始化RAII, Resource Acquisition Is Initialization)是C++编程中很重要的一项技术。其原理是在对象析构函数中释放该对象获取的资源,利用栈展开过程栈上对象的析构函数将被 自动调用的保证,从而正确地释放先前获取的资源。RAII只有在栈展开正常执行的前提下才能正常工作。函数调用和正常的C++异常处理流程(异常处于 try-catch块)都存在栈展开。 栈展开 最常见的栈展开就是正常的函数调用,. 阅读全文
posted @ 2012-07-10 10:57 Mr.Rico 阅读(389) 评论(0) 推荐(0) 编辑
摘要:C++的类型萃取技术 自从C++中引入了template后,以泛型技术为中心的设计得到了长足的进步。STL就是这个阶段杰出的产物。STL的目标就是要把数据和算法分开,分别对其进行设计,之后通过一种名为iterator的东西,把这二者再粘接到一起。设计模式中,关于iterator的描述为:一种能够顺序访问容器中每个元素的方法,使用该方法不能暴露容器内部的表达方式。可以说,类型萃取技术就是为了要解决和iterator有关的问题的,下面,我们就来看看整个故事。应该说,迭代器就是一种智能指针,因此,它也就拥有了一般指针的所有特点——能够对其进行*和->操作。但是在遍历容器的时候,不可... 阅读全文
posted @ 2012-07-01 12:48 Mr.Rico 阅读(455) 评论(0) 推荐(1) 编辑
摘要:读书不是目的,关键在于思考。 很早就在水木上看到有人推荐《The C Programming Language》这本书,一直都没看,开学一个月就专心拜读了一下,并认真做了课后习题。读来收获不少,主要有两点:一是加深了自己对一些基础知识的理 解和感悟;二是从中学到了一些不错的编程风格和设计思想,这些东西虽看起来不起眼但细细嚼来还是很值得学习的。下面就从四个方面做一个小总结,水平有限, 加之刚读第一遍,难免有疏漏和错误,非常欢迎批评补充。 ===读书感悟=== ===设计思想=== ===编程风格=== ===经典例程===... 阅读全文
posted @ 2012-06-27 22:10 Mr.Rico 阅读(2292) 评论(0) 推荐(0) 编辑
摘要:之前有篇文章讨论过C/C++中的内存存储问题:http://www.cnblogs.com/xkfz007/articles/2490175.html这一篇是主要介绍C++中堆和栈的区别。 C++作为一款C语言的升级版本,具有非常强大的功能。它不但能够支持各种程序设计风格,而且还具有C语言的所有功能。我们在这里为大家介绍的是其中一个比较重要的内容,C++内存区域的基本介绍。 C++内存区域分为5个区域。分别是堆,栈,自由存储区,全局/静态存储区和常量存储区。 栈:由编译器在需要的时候分配,在不需要的时候自动清除的变量存储区。里面通常是局部变量,函数参数等。 堆:由new分配的内存块,他们的释放 阅读全文
posted @ 2012-06-22 20:12 Mr.Rico 阅读(358) 评论(0) 推荐(0) 编辑
摘要:《C++ Templates》读书笔记(一):模板参数2009-08-17 12:48有三种模板参数(形参):(1)类型参数(这是使用得最多的)(2)非类型参数(3)模板的模板参数类型参数: 类型参数是通过关键字typename或者class引入。关键字后面必须是一个简单的标识符,后面用逗号来隔开下一个参数声明,等号代表接下来的是缺省模板实参,一个封闭的尖括号(>)表示参数化子句的结束。 在模板声明内部,类型参数的作用类似于typedef名称。例如,如果T是一个模板参数,就不能使用诸如class T等形式的修饰名称,即使T是一个要被class类型替换的参数也不可以。 template & 阅读全文
posted @ 2012-06-22 09:04 Mr.Rico 阅读(582) 评论(0) 推荐(0) 编辑
摘要:模板类中操作符重载问题("<<"和">>"重载)在模板类中输入流“>>”和输出流“<<”的重载,若使用友元在类内声明,在类外实现,那么连接时将会报错,但我们可以采用以下三种方式来实现输出流"<<"和"输入流>>"的重载。 一、将输出流"<<"和"输入流>>"重载的实现写在类中 #include"stdafx.h"#include<iostream>u 阅读全文
posted @ 2012-06-04 11:11 Mr.Rico 阅读(9807) 评论(0) 推荐(2) 编辑
摘要:什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器。很简单,容器就是保存其它对象的对 象,当然这是一个朴素的理解,这种“对象”还包含了一系列处理“其它对象”的方法,因为这些方法在程序的设计上会经常被用到,所以容器也体现了一个好处, 就是“容器类是一种对特定代码重用问题的良好的解决方案”。 容器还有另一个特点是容器可以自行扩展。在解决问题时我们常常不知道我们需要存储多少个对象,也就是说我们不知道应该创建多大的内存空间来保存我们的对象。 显然,数组在这一方面也力不从心。容器的... 阅读全文
posted @ 2012-06-04 10:30 Mr.Rico 阅读(11479) 评论(0) 推荐(5) 编辑
摘要:如果用户熟悉Linux下的sed、awk、grep或vi,那么对正则表达式这一概念肯定不会陌生。由于它可以极大地简化处理字符串时的复杂度,因此现在已经在许多Linux实用工具中得到了应用。千万不要以为正则表达式只是Perl、Python、Bash等脚本语言的专利,作为C语言程序 员,用户同样可以在自己的程序中运用正则表达式。 标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数PhilipHazel的Perl-CompatibleRegularExpression库,许多Linux发行版本都带有这个函数库。 编译正则表达式 ... 阅读全文
posted @ 2012-05-20 11:16 Mr.Rico 阅读(267) 评论(0) 推荐(0) 编辑
摘要:最近在项目开发中,遇到一个异常,经过测试,发现是迭代器失效问题,于是稍微总结了一下。 vector迭代器失效测试: 测试程序: voidvectorTest(){vector<int>container;for(inti=0;i<10;i++){container.push_back(i);}vector<int>::iteratoriter;for(iter=container.begin();iter!=container.end();iter++){if(*iter>3)container.erase(iter);}for(iter=container 阅读全文
posted @ 2012-05-20 09:18 Mr.Rico 阅读(7353) 评论(0) 推荐(1) 编辑
摘要:了解各种不同意义的new 和 delete C++中关于new 的形态主要有三种:new operator, operator new, placement new 三者的用法有着不同,注意区别适用的条件: new operator: new 操作符,和C++语言其它操作符(如+, -, ->, ::....)一样,是由语言内建的,总是完成相同的事情,程序员不能改变其意义。如下为new的一种用法: string *ps = new string("hazirguo"); 它主要完成的任务包括三个方面: 分配足够的内存,用来放置某类型对象。上例中分配足够放置一个stri 阅读全文
posted @ 2012-05-17 13:19 Mr.Rico 阅读(329) 评论(0) 推荐(0) 编辑
摘要:了解临时对象的来源 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象. 通常出现在以下两种情况: (1)为了使函数调用成功而进行隐式类型转换的时候。 传递某对象给一个函数,而其类型与函数的形参类型不同时,如果可以通过隐式转化的话可以使函数调用成功,那么此时会通过构造函数生成一个临时对象,当函数返回时临时对象即自动销毁。如下例: //计算字符ch在字符串str中出现的次数 int countChar (const string& str, char ch); char buffer[];... 阅读全文
posted @ 2012-05-17 12:46 Mr.Rico 阅读(20656) 评论(10) 推荐(8) 编辑
摘要:C语言可变参数实现 第一:什么是可变参数int printf(const char* format, ...);看到printf的定义大家就知道了,只有一个固定的const char*参数,后面的都是不定长的参数列表了。第二:自己写一个可变参数函数1.参数形参方式,跟printf类似,第一个为固定参数,后面的用...代替;2.包含stdarg.h头文件,因为需要用到几个里面定义的宏;void va_start(va_list arg_ptr, prev_param);type va_arg(va_list arg_ptr, type);void va_end(va_list arg_ptr). 阅读全文
posted @ 2012-05-15 15:48 Mr.Rico 阅读(979) 评论(0) 推荐(2) 编辑