C/C++ 安全释放指针的方法

代码如下: #include <stdio.h> #include <stdlib.h> #define SAFE_FREE(ptr) do { free(ptr); ptr = NULL; } while(0) #define SAFE_DEL(ptr) do { delete ptr; ptr = NULL; } while(0) #define SAFE_DELARR(ptr) do { delete [] ptr; ptr = NULL; } while(0) int main(int argc, char **argv) { char* p = new char[100]; SAFE_DELARR(p); //system("pause"); return 0; } 实现安全释放指针的机制正是上面的三个宏,其本质就是在释放了指针后,一定要及时地把指针置为NULL。宏体用 do { ... } while(0) 包裹,避免在 if/else 语句中使用时出现编译错误。 注意:上面的代码包括了delete, delete[], 因此是段 C++代码。C的话只要第一个宏即可。

2015年3月10日 · 1 分钟 · Jid

Linux Locale 详解:从原理到配置

Locale 是 Linux 国际化(i18n)的核心概念。理解它,是解决中文显示、输入问题的基础。 一、为什么需要设定 Locale 设定 Locale 与浏览中文网页无关。 即使 Locale 设为 en_US.ISO-8859-1,只要有合适的字体,浏览器照样能显示中文——浏览器自己会检测网页编码并选择对应的字体渲染。 但 Locale 与"写中文"直接相关。 如果你需要在终端输入中文、让程序识别中文作为有效字符、让系统消息显示为中文,就必须设定正确的 Locale。 简单说:看中文靠字体,写中文靠 Locale。 二、什么是 Locale Locale 是根据用户的语言、国家/地区和文化传统定义的软件运行时语言环境。它涵盖了日常使用的方方面面: 类别 变量 控制内容 字符分类 LC_CTYPE 哪些字符是合法的、大小写转换、标点分类 排序规则 LC_COLLATE 字符串比较和排序顺序 消息语言 LC_MESSAGES 提示信息、错误信息、菜单的语言 时间格式 LC_TIME 日期时间的显示格式 数字格式 LC_NUMERIC 小数点、千分位分隔符 货币格式 LC_MONETARY 货币符号和格式 姓名格式 LC_NAME 姓名书写方式 地址格式 LC_ADDRESS 地址书写方式 电话格式 LC_TELEPHONE 电话号码格式 度量衡 LC_MEASUREMENT 公制/英制 纸张大小 LC_PAPER A4 / Letter 等 概述 LC_IDENTIFICATION Locale 自身的元数据 Locale 定义文件存放在 /usr/share/i18n/locales/,如 zh_CN、en_US 等。 ...

2015年3月9日 · 2 分钟 · Jid

Solaris 创建用户

步骤 # 1. 创建主目录 mkdir -p /export/home/username # 2. 创建用户(指定 Shell 和主目录) useradd -s /usr/bin/bash -d /export/home/username username # 3. 设置密码 passwd username # 4. 设置主目录权限 chown username /export/home/username # 5. 验证 tail -1 /etc/passwd 常用 useradd 选项 选项 作用 -s 指定登录 Shell -d 指定主目录 -g 指定主组 -G 指定附加组 -u 指定 UID -m 自动创建主目录(部分版本支持) 删除用户 userdel username # 保留主目录 userdel -r username # 同时删除主目录 参考:Solaris System Administration Guide

2015年3月8日 · 1 分钟 · Jid

man 命令:在线手册页使用指南

基本用法 man [章节号] 命令名 章节说明 章节 内容 示例 1 用户命令 man 1 ls 2 系统调用 man 2 open 3 C 库函数 man 3 printf 4 设备和特殊文件 man 4 null 5 配置文件格式 man 5 passwd 7 杂项(协议、字符集等) man 7 ascii 8 系统管理命令 man 8 mount 不指定章节号时,man 会按顺序搜索,返回第一个匹配结果。 常见陷阱 man printf # 显示第 1 章:shell 命令 printf man 3 printf # 显示第 3 章:C 库函数 printf 两者完全不同。查 C 函数时务必指定章节号 3。 实用技巧 # 搜索手册页(不知道完整名称时) man -k "copy files" # 等同于 apropos # 在 man 页面内搜索 # 按 / 输入关键词,n 下一个,N 上一个 # 查看手册页存储路径 man --path # 以网页方式打开(部分系统支持) man -H firefox open

2015年3月6日 · 1 分钟 · Jid

touch 命令:创建空文件或更新时间戳

功能 touch 有两个用途: 创建空文件 — 如果文件不存在,创建一个大小为 0 的空文件 更新时间戳 — 如果文件已存在,更新其访问时间和修改时间为当前时间 常用示例 # 创建空文件 touch newfile.txt # 同时创建多个文件 touch file1.txt file2.txt file3.txt # 更新已有文件的时间戳 touch existing.txt # 只更新访问时间(不修改 mtime) touch -a file.txt # 只更新修改时间(不修改 atime) touch -m file.txt # 设置为指定时间(格式:YYYYMMDDhhmm) touch -t 202604011200 file.txt

2015年3月5日 · 1 分钟 · Jid

Linux/Unix 修改 PATH 环境变量

问题 安装软件后执行命令提示 command not found,但程序确实已经安装。原因是程序所在目录不在 PATH 搜索路径中。 查看当前 PATH echo $PATH 输出是以冒号分隔的目录列表,Shell 会依次在这些目录中查找可执行文件。 添加路径 Bash(大多数 Linux 默认) 编辑 ~/.bashrc 或 ~/.profile,添加: export PATH=$PATH:/新路径 例如: export PATH=$PATH:/usr/local/bin:$HOME/bin C Shell 编辑 ~/.cshrc,添加: set path=($path /usr/local/bin $home/bin) 使配置生效 source ~/.bashrc # Bash source ~/.cshrc # C Shell 或重新登录。 全局设置(所有用户) Bash:编辑 /etc/profile 或 /etc/profile.d/ 下创建脚本 所有 Shell:编辑 /etc/environment(格式为 PATH="/usr/local/sbin:/usr/local/bin:...")

2015年3月4日 · 1 分钟 · Jid

获取整数的最大值最小值的宏定义及可能出现的问题

在C/C++编程中时常需要使用整数的最大值最小值,通常这两个常用是跟平台和操作系统有关的,不同的平台会有不同的值,因此可移植的办法就是使用库函数提供的常量定义。 (1)类似的常量定义在limits.h和float.h头文件中,可以查看源文件获取类似常量的使用办法。在头文件中,整数的最值通常是这样的名字:INT_MAX, INT_MIN,直接使用即可。 (2)当然这两个最值完全可以通过编程实现: #define MAX_INT ((unsigned)(-1)>>1) #define MIN_INT (~MAX_INT) 但是,这两个宏仅仅是没有类别的符号,在使用的时候会陷入困境。看下面这段C++程序,输出结果出乎意料。 #include <iostream> #include <limits> #define MAX_INT ((unsigned)(-1)>>1) #define MIN_INT (~MAX_INT) int main() { std::cout << "max_int: " << MAX_INT << "\n" << "min_int: " << MIN_INT << std::endl; } 输出结果是 max_int: 2147483647 min_int: 2147483648 结果怎么会是这样呢? 问题出在类型上:~MAX_INT 中 MAX_INT 是 unsigned 表达式,对 unsigned 取反得到的还是 unsigned,值为 0x80000000(即无符号的 2147483648)。cout 按 unsigned 输出,所以显示的不是 -2147483648。正确的办法是强制转换: cout << "max_int: " << (int)MAX_INT << "\n" << "min_int: " << (int)MIN_INT << endl; 当然最好的办法还是不要使用#define这个宏,不安全。 (3)针对上面的问题,一个比较好的解决办法是,直接定义常量: const int MAX_INT = ((unsigned)(-1))>>1; const int MIN_INT = ~MAX_INT; 注意:这里的 MAX_INT 是 const int(有符号),与方案 (2) 中 #define 展开后的 unsigned 表达式不同。~MAX_INT 对有符号 int 取反,结果为 -2147483648,printf 用 %d 输出即可正确显示。 ...

2015年3月3日 · 1 分钟 · Jid

Cygwin 安装完整 man-pages

问题 Cygwin 自带的 man pages 不完整,比如 man listen、man socket 等系统调用没有文档。 解决方法 方法一:编译安装(推荐) # 1. 下载最新 man-pages # https://www.kernel.org/pub/linux/docs/man-pages/ # 2. 解压 tar zxvf man-pages-3.41.tar.gz cd man-pages-3.41 # 3. 安装 make gz make install 方法二:手动放置 下载并解压到 Cygwin 安装目录的 %cygwin%\usr\man 下 编辑 /etc/man.conf,添加: MANPATH /usr/man/man-pages-3.41 重启 Cygwin 终端 版本号根据实际下载的版本修改。 验证 man listen man socket 能正常显示说明安装成功。

2015年3月2日 · 1 分钟 · Jid

Vim 打开文件时自动跳到上次的光标位置

问题 在 Linux 下用 Vim 打开文件时,光标总是在第一行,而不是上次退出时的位置。Windows 下的 gVim 默认支持这个功能。 解决方法 将以下代码添加到 ~/.vimrc: if has("autocmd") filetype plugin indent on augroup vimrcEx au! autocmd BufReadPost * \ if line("'\"") > 1 && line("'\"") <= line("$") | \ exe "normal! g`\"" | \ endif augroup END else set autoindent endif 原理 line("'\"") 获取上次退出时光标所在行号(Vim 自动在 .viminfo 中记录) exe "normal! g""跳转到该位置(用g` 跳转,不改变 jumplist) 判断条件确保行号有效(大于 1 且不超过文件总行数)

2015年3月1日 · 1 分钟 · Jid

Solaris 配置 NFS 共享

以下操作均需 root 权限。 服务端配置 1. 启动 NFS 服务 # Solaris 10+ svcadm enable network/nfs/server # 旧版本 /etc/init.d/nfs.server start 2. 共享目录 即时生效(重启后失效): # 只读共享 share -F nfs -d "shared dir" /export/home/shared # 读写共享,限定客户端 share -F nfs -o rw=192.168.1.100 -d "home dirs" /export/home2 永久生效: 将 share 命令写入 /etc/dfs/dfstab: share -F nfs -d "shared dir" /export/home/shared 3. 验证共享 dfshares # 或 showmount -e 客户端配置 1. 启动 NFS 客户端服务 svcadm enable network/nfs/client 2. 挂载共享目录 临时挂载: mount -F nfs 192.168.1.1:/export/home/shared /mnt/shared 永久挂载(写入 /etc/vfstab): ...

2015年2月19日 · 1 分钟 · Jid