前几天看Redis源码时,截取了一段代码交给某位同事,问他们这样写有没有问题:
typedef struct listNode{
struct listNode * prev;
struct listNode * next;
void * value;
}listNode;
list * listNode(void)
{
listNode * node;
if ((node = zmalloc(sizeof(*node))) == NULL){ //这行代码
//........
}
//.......
}
就说node是野指针,访问非法啥的。
其实这么写是没有什么问题的,虽然在栈上为node开辟的字节里的位是脏的,但这里并没有访问那个地址,而且sizeof是编译器的。就比如:
class CStu
{
int m_iData;
public:
void AccessNoMemberData()
{
cout<<"AccessNoMemberData"<<endl;
}
};
CStu * pStu = NULL;
pStu->AccessNoMemberData(); //这行代码
这样写也没问题,虽然pStu == NULL。为什么呢?这行代码最终会被编译器转化为以下可能的形式:
XXXXAccessNoMemberDataXXX(pStu)
成员函数被name mangled:XXXXAccessNoMemberDataXXX(CStu * const this);///具体可以看深度探索C++对象模型
函数内部没有通过this访问成员,哪怕是NULL也不会造成core dump【要是访问成员变量就肯定core了】,可以通过查看对应的汇编代码。
明天写下代码规范的问题和在没有core文件下如何定位造成core dump的代码行,需要懂些汇编知识。