在Linux下调试代码的过程中,使用了fprintf输出到stderr来打印调试信息,因为标准错误描述符stderr是不使用缓冲的,可以尽可能实时地将调试信息输出到屏幕上,方便更准确地定位bug。
代码使用了sqlite3的接口,从sqlite3的sqlite3_get_table函数获取到查表的结果,查询结果由该函数的第3个参数char ***pazResult来返回,即*pazResult所指向的指针数组char **中。假设查询返回了5个字段,共有3条记录,则指针数组的元素个数为20。第0个到第4个元素是各个字段名的字符串指针,第5个到第9个元素是返回的第1条记录的各个字段的值得字符串指针。以此类推。
调试的时候已经定位到了bug的位置,是对某条记录的一个字段的字符串进行读复制操作时出错的。很是蹊跷,于是使用fprintf函数输出到stderr来打印调试信息,当时检查数据库确知这条记录的该字段在数据表中为空,而使用fprintf输出字符串为"(null)"。便以为通过sqlite3的接口获取到的空字段会被处理为字符串"(null)",可是如果对该字段的字符串指针所指向的地址进行其他形式的访问时,如"%c"按单个字符输出,求字符串长度strlen等等,就会出现段错误。很是不解,后来把地址打印出来一看,原来为0。说明sqlite3对查表取到的空字段会返回NULL指针,而NULL指针作为参数传递给fprintf函数并以"%s"作为格式控制字符串时,fprintf函数会输出字符串"(null)"。
我就错在了一直以为"(null)"是sqlite3的接口返回的!!!
测试发现Linux下,printf对于NULL指针参数按"%s"格式输出时,结果也是字符串"(null)"。
阅读(2505) | 评论(1) | 转发(0) |