我知道buffer overruns是使用C风格字符串(字符数组)的一个潜在危险。如果我知道我的数据适合我的缓冲区,是否可以使用它们?我还需要注意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命令并解析其输出以获取有关操作系统的信息。将缓冲区设置为任意大小是否有任何错误(或危险)?
答案 0 :(得分:20)
C字符串有一些缺点:
答案 1 :(得分:16)
C字符串缺少C ++对应的以下方面:
答案 2 :(得分:14)
在许多应用程序中,不能在恒定时间内访问长度是一个严重的开销。
答案 3 :(得分:8)
您可能知道,今天1024字节足以包含任何输入,但您不知道明天或明年情况会如何变化。
如果过早优化是所有邪恶的根源,那么神奇的数字就是干。
答案 4 :(得分:7)
如果需要,增加字符串(字符数组)所需的内存管理等对于重新发明来说有点无聊。
答案 5 :(得分:6)
无法将NUL字符(如果您需要它们)嵌入C样式字符串中。
答案 6 :(得分:6)
好吧,为了评论您的具体示例,您不知道调用df返回的数据是否适合您的缓冲区。永远不要相信未经过传真的输入到您的应用程序中,即使它被认为是来自像df这样的已知来源。
例如,如果名为“df”的程序放在搜索路径中的某个位置,以便执行它而不是系统df,则可以使用它来利用缓冲区限制。或者如果df被恶意程序替换。
从文件读取输入时,使用一个允许您指定要读取的最大字节数的函数。在OSX和Linux下,fgets()实际上定义为char *fgets(char *s, int size, FILE *stream);
,因此在这些系统上使用是安全的。
答案 7 :(得分:3)
当你有一个字节数组而不是一串字符时,字符编码问题就会浮出水面。
答案 8 :(得分:3)
在您的特定情况下,不是c字符串是危险的,而是将不确定数量的数据读入固定大小的缓冲区。不要使用gets(char *)作为例子。
看一下你的例子,看起来似乎没有问题 - 试试这个:
char buffer[1024];
char * line = NULL;
while ((line = fgets(buffer, sizeof(buffer), fp)) != NULL) {
// parse one line of command output here.
}
这是对c字符串的完全安全使用,尽管你必须处理line
不包含整行的可能性,但是被截断为1023个字符(加上空终止符)
答案 9 :(得分:2)
我认为使用它们是可以的,人们多年来一直在使用它们。 但是如果可能的话我宁愿使用std :: string因为 1)你不必每次都这么谨慎,可以考虑你的域的问题,而不是认为你每次都需要添加另一个参数......内存管理和那种东西......它只是更安全更高层次的代码...... 2)可能还有一些其他的小问题并不重要但仍然......就像人们已经提到的那样......编码,unicode ......所有那些“相关”的东西人们创建std :: string的想法...... :)
<强>更新强>
我在一个项目上工作了半年。不知何故,我愚蠢到永远不会在发货前在发布模式下编译.... :) 嗯......幸运的是,我在3小时后发现了一个错误。 这是一个非常简单的字符串缓冲区溢出。
答案 10 :(得分:2)
现在没有Unicode支持是合理的......
答案 11 :(得分:0)
c字符串有滥用的机会,因为必须扫描字符串以确定其结束位置。
strlen - 查找长度,扫描字符串,直到您点击NUL,或访问受保护的内存
strcat - 必须扫描才能找到NUL,以确定从哪里开始连接。 c字符串中没有任何知识,无法判断是否存在缓冲区溢出。
c字符串存在风险,但通常比字符串对象快。
答案 12 :(得分:0)
因此,如果没有大的努力,就无法共享cstring copys。这在许多情况下以内存中相同cstring的不必要的复制结束。
答案 13 :(得分:0)
这个问题确实没有答案
如果你用C语写你有什么选择吗?
如果你用C ++写作,为什么要问?不使用C ++原语的原因是什么?
我能想到的唯一原因是:链接C和C ++代码并在接口中的某处使用char *。它有时候很容易使用char *而不是一直进行转换(特别是如果它真的'好'的C ++代码有3种不同的C ++字符串对象类型)。
答案 14 :(得分:0)
曾经有一种说法,即高级语言的规范定义是“比C更好的字符串处理”。
答案 15 :(得分:0)
另一个考虑因素是谁将维护您的代码?两年后怎么样?那个人会像你一样对C-stlye琴弦感到舒服吗?随着STL变得越来越成熟,人们对STL字符串的使用感觉似乎比使用C风格的字符串更加舒适。