在C/C++的一些人使用C风格的字符串,如:c风格的字符串是否安全?
char *str = "This is a c-styled string";
我的问题是这是安全的?我看到它的方式是他们创建了一个char指针,它指向一个常量字符数组的第一个字母,但不能用其他的东西,例如另一个变量覆盖内存中char数组的一部分?从而导致str逻辑无效?
在C/C++的一些人使用C风格的字符串,如:c风格的字符串是否安全?
char *str = "This is a c-styled string";
我的问题是这是安全的?我看到它的方式是他们创建了一个char指针,它指向一个常量字符数组的第一个字母,但不能用其他的东西,例如另一个变量覆盖内存中char数组的一部分?从而导致str逻辑无效?
现在,字符串常量被放在二进制文件的只读段中。如果您尝试在只读区域写入地址,则CPU的内存管理单元将导致故障,并且您的应用程序将获得访问冲突或分段错误或其他取决于操作系统的行为。
此外,如果您将字符串常量的类型声明为非常量,编译器会发出警告。
存储在只读内存部分...现在一切都很有意义... thx〜 – user176121 2009-10-11 13:40:34
非Intel-y有相当大的世界,甚至非MMU环境,在这里不会是案件。由于C或C++标准没有定义(与实现定义的*非常*不同),因此C或C++标准中没有任何内容规定了此行为。您可能想清楚地说明,对于支持它的体系结构来说,这个答案是很常见的做法,但决不是强制性的。 – paxdiablo 2009-10-12 01:56:53
1请调整参数@paxdiablo。 – 2011-05-26 18:00:51
这是不安全的。但在C/C++中也是如此。您可以轻松地覆盖其他对象使用的内存部分。
不要真正做到这一点:
int *foo = 0x1234;
byte[] bytes = (byte[]) foo;
bytes[0] = 0x56;
printf("%d\n", *foo);
也就是说,如果使用不当,任何指针是很危险的。
但不能有其他的东西,例如另一个变量覆盖内存中的字符数组的一部分?
他们一定不要那样做。其原因是,你的C-字符串字面量是一个常数和正确,应该被宣布为一个:
char const* str = "This is a c-styled string";
你(非const)代码,只允许出兼容的遗留C代码。尝试修改数据导致未定义的行为。
它应该是const char str [],它是真正的类型。为什么会丢失编译时大小信息? – 2009-10-11 14:46:18
@fnieto:好评。这会被优化为指向一个字面值,还是会被复制(尽管'const'限定符)?我恨所有我的文字字符串被复制。 – 2009-10-11 14:53:23
@fnieto:虽然语义不同。 Konrad说,如果它被声明为一个数组,你会得到一个静态分配的字符串的本地副本。用char指针,你只需指向原始的静态分配的字符串。 – jalf 2009-10-11 14:57:56
事情就像你做的一样安全。您可以像堆叠字符串一样轻松地覆盖堆栈上的整数。事实上,你的问题在某些系统中是安全的,因为它可能被放置在只读存储器部分。
如果人们不知道自己在做什么,就不应该使用C语言。就像他们不应该没有经过适当训练就使用电锯一样。 C的全部存在理由是一种系统编程语言。它给你充分的权力去做你想做的事。随着权力来自责任。
取决于你的意思是“安全”。
它们的本质安全性不低于C/C++中其他任何指针的使用。指针一般要求你对记忆非常小心。
它们与您的编程实践一样安全。只要你知道如何正确地使用它们,它们就是完全安全的。对于那些编程风格让人想到瓷器店里的大象的人来说,这样的字符串可能并不安全。但是关于整个C/C++语言可以说同样的事情。
您最初的单行申报示例已经遭遇了不安全的样式问题。在C和C++中,字符串都是不可修改的左值。创建指向这些文字的[长寿命]非常量指针并不是一个好主意。通常,它应该看起来如下
const char *str = "This is a c-styled string";
请注意额外的'const'。
(这个特殊的规则不能始终遵循在C,但通常只需要违反它在某些控制良好的本地化惯用的代码。)
这闻起来像'为const char *'。 – Zed 2009-10-11 13:28:39
也气味重复:http://stackoverflow.com/questions/349025/is-a-string-literal-in-c-created-in-static-memory – Zed 2009-10-11 13:31:04
这取决于你的“安全”的定义。使用'std :: string'肯定更安全。 – sbi 2009-10-11 15:45:45