我知道缓冲区溢出是使用C风格字符串(char数组)的一个潜在危险.如果我知道我的数据适合我的缓冲区,是否可以使用它们?我还需要注意C风格字符串固有的其他缺点吗?
编辑:这是一个接近我正在做的事情的例子:
char buffer[1024]; char * line = NULL; while ((line = fgets(fp)) != NULL) { // this won't compile, but that's not the issue // parse one line of command output here. }
此代码从使用popen("df")
命令创建的FILE指针获取数据.我正在尝试运行Linux命令并解析其输出以获取有关操作系统的信息.以这种方式将缓冲区设置为任意大小是否有任何错误(或危险)?
C字符串有一些缺点:
获得长度是一项相对昂贵的操作.
不允许嵌入的nul字符.
字符的签名是实现定义的.
字符集是实现定义的.
char类型的大小是实现定义的.
必须分别跟踪每个字符串的分配方式,以及它必须如何被释放,或者即使它根本需要被释放.
无法将字符串切片称为另一个字符串.
字符串不是不可变的,这意味着它们必须单独同步.
字符串无法在编译时进行操作.
切换案例不能是字符串.
C预处理器无法识别表达式中的字符串.
无法将字符串作为模板参数传递(C++).
C字符串缺少C++对应的以下方面:
自动内存管理:您必须手动分配和释放内存.
连接效率的额外容量:C++字符串的容量通常大于其大小.这允许在没有许多重新分配的情况下增加大小.
没有嵌入的NUL:根据定义,NUL字符结束C字符串; C++字符串保留一个内部大小计数器,因此它们不需要特殊值来标记它们的结尾.
明智的比较和赋值运算符:即使允许比较C字符串指针,它几乎总是不是预期的.类似地,分配C字符串指针(或将它们传递给函数)会产生所有权歧义.
在许多应用中,不能在恒定时间内访问长度是一个严重的开销.
您可能知道,今天1024字节足以包含任何输入,但您不知道明天或明年的情况会如何变化.
如果过早优化是所有邪恶的根源,魔术数字就是干.
如果需要,内存管理等需要增长字符串(字符数组),有点无聊重新发明.
没有办法将NUL字符(如果你需要它们)嵌入到C样式字符串中.
好吧,为了评论您的具体示例,您不知道调用df返回的数据是否适合您的缓冲区.永远不要相信未经过传真的输入到您的应用程序中,即使它应该来自像df这样的已知来源.
例如,如果名为"df"的程序放在搜索路径中的某个位置,以便执行它而不是系统df,则可以使用它来利用缓冲区限制.或者如果df被恶意程序替换.
从文件读取输入时,使用一个允许您指定要读取的最大字节数的函数.在OSX和Linux下,fgets()实际上被定义为 char *fgets(char *s, int size, FILE *stream);
在这些系统上使用它们是安全的.