在 c/c++ 中,有些人使用 c 风格的字符串,例如:
char *str = "This is a c-styled string";
我的问题是这样安全吗?我看到它的方式是他们创建了一个 char 指针,该指针指向一个 const 字符数组的第一个字母,但不能有其他东西,例如另一个变量覆盖内存中 char 数组的一部分吗?从而导致 str 在逻辑上无效?
如今,字符串常量被放置在二进制文件的只读部分中。如果您尝试写入只读部分中的地址,CPU 的内存管理单元将导致错误,您的应用程序将出现访问冲突或分段错误或其他一些依赖于操作系统的行为。
此外,如果您将字符串常量的类型声明为非常量,编译器会发出警告。
但是不能有其他东西,例如另一个变量覆盖内存中char数组的一部分吗?
他们不能那样做。原因是您的 C 字符串文字是一个常量,正确地它应该被声明为一个:
char const* str = "This is a c-styled string";
您的(非常量)代码只允许与旧版 C 代码不兼容。尝试修改数据会导致未定义的行为。
事情就像你做的一样安全。您可以像覆盖字符串一样轻松地覆盖堆栈上的整数。实际上,您的问题中的内容更安全(在某些系统中),因为它很可能放置在只读内存部分中。
如果人们不知道自己在做什么,就不应该使用 C。就像他们不应该在没有经过适当培训的情况下使用电锯一样。C 的全部存在理由是一种系统编程语言。它为您提供了做您想做的事的全部权力。权力伴随着责任。
这是不安全的。但是 C/C++ 中的任何其他东西也是如此。您可以轻松覆盖其他对象使用的内存部分。
它们与您的编程实践一样安全。只要您知道如何正确使用它们,它们就绝对安全。对于那些编程风格让人联想到瓷器店里的大象的人来说,这样的字符串可能并不安全。但是对于整个 C/C++ 语言也可以这样说。
您最初的单行声明示例已经存在不安全的样式问题。在 C 和 C++ 中,字符串文字都是不可修改的左值。创建指向此类文字的 [长期存在的] 非常量指针不是一个好主意。通常,它应该如下所示
const char *str = "This is a c-styled string";
请注意额外的“常量”。
(这个特定的规则在 C 中不能总是遵循,但通常只需要在一些控制良好的本地化惯用代码中违反它。)
实际上不要这样做:
int *foo = 0x1234;
byte[] bytes = (byte[]) foo;
bytes[0] = 0x56;
printf("%d\n", *foo);
也就是说,如果滥用任何指针都是危险的。
取决于您所说的“安全”。
它们在本质上的安全性并不低于 C/C++ 中指针的任何其他使用。指针通常要求您对内存非常小心。