C语言
文章平均质量分 84
鱼思故渊
这个作者很懒,什么都没留下…
展开
-
boost::shared_ptr的使用方法
1. boost::shared_ptr的用法 下面用一个简单的例子说明shared_ptr的用法: #include #include class A {public: void print() { printf("class A print!\n"); }};int main(int argc, char **argv) {原创 2014-02-27 21:59:15 · 21398 阅读 · 2 评论 -
什么是野指针?迷途指针!悬空指针!
一、迷途指针迷途指针与野指针指的是不指向任何合法的对象的指针。当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称迷途指针。若操作系统将这部分已经释放的内存重新分配给另外一个进程,而原来的程序重新引用现在的迷途指针,则将产生无法预料的后果。因为此时迷途指针所指向的内存现在包含的已经完全是不同的数据。通常来说,若原来的程序继续原创 2014-02-28 08:20:15 · 5904 阅读 · 5 评论 -
realloc malloc calloc 三个函数的区别
三个函数的申明分别是: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(size_t numElements, size_t sizeOfElement); 都在stdlib.h函数库内它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL原创 2014-02-18 13:53:59 · 1666 阅读 · 0 评论 -
linux多线程编程--信号量和条件变量 唤醒丢失事件
关于linux下信号量和条件变量的使用,在很多地方都可以找到相关文章,信号量、条件变量、互斥锁都是线程同步原语,在平时多线程编程中只要知道一两种就可以轻松搞定,我也是这么认为的,但是今天发现,有时还是有区别的。 在实现多线程编程中,其中有些东西是可以互相转换的,比如使用信号量可以实现条件变量,关于这三者的基本用法不在累述,我的博客中也有相关介绍,这里介绍条件变量丢失唤醒事件的事情。原创 2014-03-01 14:26:37 · 7312 阅读 · 10 评论 -
linux网络编程--TCP/IP网络编程中socket的行为
熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉:1. TCP/IP协议(如连接的建立和终止、重传和确认、滑动窗口和拥塞控制等等)2. Socket I/O系统调用(重点如read/write),这是TCP/IP协议在应用层表现出来的行为。3. 编写Performant, Scalable的服务器程序。包括多线程、IO Multiplexing、非阻塞、异步原创 2014-03-03 09:39:13 · 3044 阅读 · 0 评论 -
同步I/O--fdatasync与fsync
对于提供事务支持的数据库,在事务提交时,都要确保事务日志(包含该事务所有的修改操作以及一个提交记录)完全写到硬盘上,才认定事务提交成功并返回给应用层。一个简单的问题:在*nix操作系统上,怎样保证对文件的更新内容成功持久化到硬盘? 1. write不够,需要fsync一般情况下,对硬盘(或者其他持久存储设备)文件的write操作,更新的只是内存中的页缓存(page cache),原创 2014-03-03 11:50:06 · 1756 阅读 · 0 评论 -
网络编程--回调函数 阻塞操作 异步执行
其实写这篇文章的目的是这样的:在基本的网络库中,经常看到有注册回调这么一说,让回调函数做真正去做的事情,在libevent中就是这样。这样做的目的说了为了避免阻塞,避免异步(这里首先说明异步和阻塞是不同的概念)。但是我的问题是:如果在回调中执行了很耗时的操作,甚至是在回调中出现了阻塞的操作,这该怎么办?还有就是,在执行回调函数的部分时,是不是流程和回调函数的内容顺序执行的,想执行中断那样,不管怎么原创 2014-03-03 22:53:40 · 4496 阅读 · 0 评论 -
栈与堆空间
一个由C/C++编译的程序占用的内存分为以下几个部分: 1、栈区(stack):又编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈。 2、堆区(heap):一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收,值得注意的是他与数据结构的堆是两回事,分配方式倒是类似于数据结构的链表。 3、全局区(static):也叫静态数据内存空间,存储转载 2014-03-30 09:03:57 · 943 阅读 · 0 评论 -
线程安全与可重入
首先可以参考维基百科中关于线程安全和可重入的解释来思考问题,两个是不同的概念,摘录维基百科的一段解释:可重入与线程安全两个概念都关系到函数处理资源的方式。但是,他们有一定的区别。可重入概念会影响函数的外部接口,而线程安全只关心函数的实现。大多数情况下,要将不可重入函数改为可重入的,需要修改函数接口,使得所有的数据都通过函数的调用者提供。要将非线程安全的函数改为线程安全的,则原创 2014-02-27 22:09:38 · 1646 阅读 · 0 评论 -
回调函数在非阻塞模式中的使用
本来是想介绍回调函数在非阻塞模式的地位,但是在这之前需要知道这些基本知识。然后再验证回调函数的作用一、同步与异步同步/异步, 它们是消息的通知机制1. 概念解释A. 同步所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。按照这个定义,其实绝大多数函数都是同步调用(例如sin isdigit等)。但是一般而言,我们在说同步、异步的时候,特原创 2014-02-26 11:15:13 · 3993 阅读 · 0 评论 -
linux内核分析--内核中的数据结构之红黑树(续)
#include#include #include "kn_common.h"MODULE_LICENSE("Dual BSD/GPL");struct student{ int id; char* name; struct rb_node node;};static int insert_student(struct student*, struct r原创 2014-02-25 16:31:57 · 1855 阅读 · 0 评论 -
C++ 智能指针详解
C++ 智能指针详解 一、简介由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见。用智能指针便可以有效缓解这类问题,本文主要讲解参见的智能指针的用法。包括:std::auto_ptr、boost::scoped_p原创 2013-12-31 10:04:06 · 1405 阅读 · 2 评论 -
海量数据处理之归并、堆排、前K方法的应用:一道面试题
最初关注海量处理方面是因为好久以前在西安交大BBS算法版上看到一个牛人总结的帖子,收集了起来,后来发现网上铺天盖地地转载过,那个帖子提供了一些解决问题很好的思路,所以就零碎地整理过海量数据处理方面的一些方法,但终归没有深入并做一个稍微细致的思考,从这篇博文开始,希望能坚持整理出来。下面一道面试题是以前大雄考过我的,据说是那时一些公司常问的类型题目,这里回顾并总结一下,欢迎大家讨论并提出问题。原创 2014-01-12 08:52:28 · 2210 阅读 · 0 评论 -
Reactor的事件处理机制
首先来回想一下普通函数调用的机制:程序调用某函数Æ函数执行,程序等待Æ函数将结果和控制权返回给程序Æ程序继续处理。Reactor释义“反应堆”,是一种事件驱动机制。和普通函数调用的不同之处在于:应用程序不是主动的调用某个API完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果相应的时间发生,Reactor将主动调用原创 2014-01-13 09:12:32 · 1970 阅读 · 0 评论 -
linux内核分析--内核中的数据结构之队列(二)
内核中的队列是以字节形式保存数据的,所以获取数据的时候,需要知道数据的大小。如果从队列中取得数据时指定的大小不对的话,取得数据会不完整或过大。内核中关于队列定义的头文件位于: include/linux/kfifo.h头文件中定义的函数的实现位于:kernel/kfifo.c内核队列编程需要注意的是:队列的size在初始化时,始终设定为2的n次方使用队列之前将队列结构体中的原创 2014-02-25 11:20:15 · 3899 阅读 · 0 评论 -
linux内核--使用内核队列实现ringbuffer(续)
一、ring buffer 在以前的一篇文章--网络编程中接受缓冲的ringbuf的简单实现介绍了一个自己写的ringbuffer,其实原理和linux内核中的队列很相似,思想是一样的,只不过处理的没有内核那么恰当巧妙,这里也可以使用linux内核中的队列实现之。/**@brief 仿照linux kfifo写的ring buffer *@atuher Anker date:原创 2014-02-25 11:39:20 · 6754 阅读 · 1 评论 -
linux内核分析--内核中使用的数据结构之哈希表hlist(三)
前言:1.基本概念:散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。2. 常用的构造散列函数的方法散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位。散列表的常原创 2014-02-25 14:46:41 · 2275 阅读 · 3 评论 -
linux内核分析--内核中的数据结构之红黑树(四)
红黑树由于节点颜色的特性,保证其是一种自平衡的二叉搜索树。红黑树的一系列规则虽然实现起来比较复杂,但是遵循起来却比较简单,而且红黑树的插入,删除性能也还不错。所以红黑树在内核中的应用非常广泛,掌握好红黑树,即有利于阅读内核源码,也可以在自己的代码中借鉴这种数据结构。红黑树必须满足的规则:所有节点都有颜色,要么红色,要么黑色根节点是黑色,所有叶子节点也是黑色叶子节点中不包含数据非原创 2014-02-25 16:13:42 · 2914 阅读 · 1 评论 -
C++中RAII的惯用方法
软件开发中,会用到各种各样的资源。狭义的资源指内存,而广义的资源包括文件、网络连接、数据库连接、信号量、事件、线程、内存等,甚至可以是状态。资源获取后由于种种原因导致永久不能释放的资源称为资源泄漏。针对资源泄漏,提出了各种各样的软件机制和程序设计惯用法,如垃圾收集、RRID[1]、RAII、确定性资源清理等。RAII是C++语言的一种管理资源、避免泄漏的惯用法。C++标准保证任何情况下,已构造原创 2014-03-19 08:55:07 · 2388 阅读 · 0 评论 -
堆和栈空间的区别
堆和栈的对比: 栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而堆是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。栈空间分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloca函数完成。原创 2014-03-31 19:36:10 · 1789 阅读 · 0 评论 -
C语言中变长数组的使用方法
先说说我的理解:struct example{ __u16 tag_type; __u16 tag_len; char tag_data[0];} __attribute ((packed));1. 存在的意义:当结构体的长度变长时,例如里面有一个字符串时,为了方便管理内存。这个结构体不要用struct example a的方式定义, 而应用str原创 2014-12-28 10:10:47 · 16781 阅读 · 1 评论 -
C语言结构体声明中冒号的使用(占位符) & C结构体的乱序初始化
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域原创 2014-12-28 10:58:38 · 7090 阅读 · 1 评论 -
C语言中宏的高级用法
1、前言 今天看代码时候,遇到一些宏,之前没有见过,感觉挺新鲜。如是上网google一下,顺便总结一下,方便以后学习和运用。C语言程序中广泛的使用宏定义,采用关键字define进行定义,宏只是一种简单的字符串替换,根据是否带参数分为无参和带参。宏的简单应用很容易掌握,今天主要总结一下宏的特殊符号及惯用法。 (1)宏中包含特殊符号:#、##. (2)宏定义用do{ }w转载 2014-12-28 13:50:43 · 983 阅读 · 0 评论 -
C++ primer(八)--内联函数 引用变量 函数重载/模板/模板具体化
一、内联函数 常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中。编译过程的最终产品是可执行程序--由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈,跳到标记函数起点的内存单元,执行函数代码,然后跳回到地址被保存的指令处。来回跳跃并原创 2013-10-08 18:31:18 · 1550 阅读 · 0 评论 -
标准C++ 中STL 类的简单介绍
SGI -- Silicon Graphics[Computer System] Inc.硅图[计算机系统]公司.STL -- Standard Template Library标准模板库。 容器的概念所谓STL容器,即是将最常运用的一些数据结构(data structures)实现出来。容器是指容纳特定类型对象的集合。根据数据在容器中排列的特性,容器可概分为序列式(seque原创 2013-12-31 10:13:35 · 1985 阅读 · 0 评论 -
C++类的访问权限问题
为了更加方便的记忆,还是梳理下这些老掉牙的关系,这样也更加深刻。C++类中的访问权限问题---public/protected/private 2012-05-31 19:48:21| 分类:c++基础的东东| 标签:|字号大中小订阅C++中public,protected,private访问小结第一:private,public,pro原创 2013-10-12 22:09:30 · 1298 阅读 · 0 评论 -
C++ primer(七)--函数、C++的编程模块 函数指针 函数指针数组 typedef
当你发现自己那一块一知半解时,随便找一本经典书籍的相关章节,如果从书的目录上发现标题就有让你有种非得马上看完的冲动时,你就真的找对书了!!一个模块一个模块的攻击点,按部就班,循序渐进,还是那句看到的话,难的不是技术本身,而是对待技术学习技术的态度!!抓紧时间!!!!在以后介绍知识点的是时候,博客不再采用以前的那种规中规矩的模式,希望能够以更加突出重点、更加有侧重、更加鲜明的写法来讲述!原创 2013-10-07 15:22:39 · 1478 阅读 · 0 评论 -
C语言的字节对齐 #pragma pack(n)2
#pragma pack(n)解释一:每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。 规则: 1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据原创 2015-03-23 15:10:35 · 4469 阅读 · 0 评论 -
linux内核分析--内核中的数据结构之双链表(一)
下面直接进入正题:在了解了基本内容看具体实现,只知道数据成员list的地址,怎样去访问自身以及其他成员呢?在include/linux/list.h头文件中可以看到这段代码!#define list_entry(ptr,type,member) / container_of(ptr,type,member)其中container_of这个宏在/include/linu原创 2014-02-24 21:12:10 · 5188 阅读 · 0 评论 -
栈的区别_堆栈的访问效率_关键字static的作用是什么_关键字const有什么含意
关键字static的作用是什么? 这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:1) 无论在函数体内,类内,还是全局变量,全局静态变量,在程序启动的时候,静态变量,全局变量的空间已经分配好了。2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。3原创 2014-04-08 16:53:50 · 2253 阅读 · 0 评论 -
linux内核分析--内核中的数据结构之双链表(续)
在解释完内核中的链表基本知识以后,下面解释链表的重要接口操作:1. 声明和初始化实际上Linux只定义了链表节点,并没有专门定义链表头,那么一个链表结构是如何建立起来的呢?让我们来看看LIST_HEAD()这个宏:#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) struct原创 2014-02-24 21:52:16 · 2019 阅读 · 0 评论 -
C/C++程序内存分布
一个由C/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。程序结束时由编译器自动释放。2、堆区(heap) — 在内存开辟另一块存储区域。一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。转载 2014-03-31 17:54:57 · 1133 阅读 · 0 评论 -
智能指针 shared_ptr 的使用方法
基于Boost库, C++11 加入了shared_ptr和weak_ptr. 它们最早在TR1中就被引入, 但在C++11中, 在Boost的基础上又加入了新的功能.std::shared_ptr使用引用计数. 每一个shared_ptr的拷贝都指向相同的内存. 在最后一个shared_ptr析构的时候, 内存才会被释放. std::shared_ptr p1(new int(5原创 2014-03-25 09:29:36 · 16851 阅读 · 2 评论 -
#define的高级用法
===========================================================define中的三个特殊符号:#,##,#@===========================================================#define Conn(x,y) x##y#define ToChar(x原创 2014-05-09 17:55:11 · 2753 阅读 · 1 评论 -
标准I/O库的缓冲机制
标准I/O库提供缓冲的目的是尽可能减少使用read和write调用的次数。它也对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。标准I/O提供了三种类型的缓冲:(1)全缓冲。这种情况下,在填满标准I/O缓冲区后才进行实际的I/O操作。对于驻留在磁盘上的文件通常是由标准I/O库实施全缓冲的。在一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc原创 2014-04-10 15:35:03 · 1935 阅读 · 0 评论 -
带缓冲I/O 和不带缓冲I/O的区别与联系
首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用。系统内核对磁盘的读写都会提供一个块缓冲,当用write函数对其写数据时,直接调用系统调用,将数据写入到块缓冲进行排队,当块缓冲达到一定的量时,才会把数据写入磁盘。因此所谓的不带缓冲的I/O是指进程不提供缓冲功能(但内核还是提供缓冲的)。每调用一次write或read函数,直接系统调用。而原创 2014-04-10 15:38:45 · 5652 阅读 · 2 评论 -
十进制小数和二进制小数之间的转换
一、二进制数转换成十进制数 由二进制数转换成十进制数的基本做法是,把二进制数首先写成加权系数展开式,然后按十进制加法规则求和。这种做法称为"按权相加"法。二、十进制数转换为二进制数 十进制数转换为二进制数时,由于整数和小数的转换方法不同,所以先将十进制数的整数部分和小数部分分别转换后,再加以合并。 1. 十进制整数转换为二进制整数 十进制整数转换为二进制原创 2015-08-20 14:50:05 · 6701 阅读 · 0 评论 -
C程序设计语言--指针和引用的区别
在看了一篇文章以后,http://coolshell.cn/articles/7992.html,说的是C和C++之间的缺陷,当然这篇文章说的非常高深了。所以就找了一些资料,分析了这两者的区别在《Effective c++》一书中页介绍了关于指针和引用的区别,但是这本书安排在接下来才看!!一、引用简介 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。原创 2013-10-05 14:55:46 · 2187 阅读 · 0 评论 -
C语言程序设计--函数和程序结构
ANSI表征对C语言所作的最明显的修改是函数声明与函数定义这两个方面。当然,这也只能从宏观上讲解其中的奥妙。在这里使用了getline函数int getline(char s[],int lim){ int c,i; while(--lim>0&&(c=getchar())!=EOF&&c!='\n') s[i++]=c; if(c原创 2013-10-04 12:19:24 · 2053 阅读 · 0 评论 -
C程序设计语言--变量在内存中的分布 堆、栈、数据段、bss段、文本段
为了弄清楚这个问题,先看看在C语言中变量的分类首先查看这篇文章。一、linux的进程内存分布 1)主要是由从小到大的地址空间分布,从低地址到高地址依次是:文本段(text),数据段,BSS段,堆,栈。文本段:文本段中存放的是代码,只读数据,字符串常量(我们通常说保存在文字常量中,实际就是在文本段)数据段:数据段用来存放可执行文件中已经初始化的全局变量,全局变量又可细分为全原创 2013-10-05 11:51:24 · 3657 阅读 · 0 评论