为什么这个包含常量指针的C代码会在我身上崩溃?
可能重复:为什么这个包含常量指针的C代码会在我身上崩溃?,c,code-analysis,C,Code Analysis,可能重复: 这是我的密码: char *const p1 = "john"; p1[2] = 'z'; //crashes printf("%s\n", p1); 我知道p1是一个“只读”变量,但我认为我仍然可以修改字符串(“john”)。非常感谢您的提示和建议。您的指针指向不允许更改的内存(常量字符串) docharp1[100]=“john”这是因为不应该修改常量:毕竟,它们被称为常量是有原因的。根据C标准,修改常量是未定义的行为,这通常意味着您的程序将崩溃 请注意,这与指针是常量
这是我的密码:
char *const p1 = "john";
p1[2] = 'z'; //crashes
printf("%s\n", p1);
我知道p1是一个“只读”变量,但我认为我仍然可以修改字符串(“john”)。非常感谢您的提示和建议。您的指针指向不允许更改的内存(常量字符串)
do
charp1[100]=“john”代码>这是因为不应该修改常量:毕竟,它们被称为常量是有原因的。根据C标准,修改常量是未定义的行为,这通常意味着您的程序将崩溃
请注意,这与指针是常量无关:崩溃是因为指针指向的是字符串常量
以下是如何合法地做你想做的事情:
char p1[] = "john";
p1[2] = 'z'; //no longer crashes :)
printf("%s\n", p1);
即使指针看起来不像const
,也无法安全地修改字符串文本。它们通常被分配到只读内存中,因此您的崩溃——当它们不在只读内存中时,修改它们可能会产生意外的后果
如果复制到阵列,这应该可以工作:
char tmp[] = "john";
char *const p1 = tmp;
p1[2] = 'z'; // ok
关键字const
表示该类型的变量应保持不变。你不应该改变它
即使您将此字符串声明为char*p1=“john”代码>它将是常量字符串文字,更改它将导致未定义的行为。您应该将其声明为charp1[]=“john”代码>以实现您想要的行为。1)忘记“const”限定符。C和C++在任何平台上都是错误的:
char *p1 = "john";
p1[2] = 'z'; //crashes
原因如下:
2) 那么,如何避免访问冲突呢
简单:分配可写内存(而不是写入字符串常量,该常量可能在只读内存中分配):
3) 好的:那么“const”是怎么回事
那部分你是对的。以下是关于“常量指针”和“指向常量的指针”之间(细微)区别的(众多)讨论之一:
该代码中有两个不相关的问题。首先,常量不在正确的位置
char * const p = "john";
char const * p = "john";
const char * p = "john";
后两个是指向不可修改字符串的指针。如果您这样做了,那么代码就不会编译了
第一个选项char*const
实际上不是只读变量。它表示指向可修改数据的指针,并且该指针不能更改为指向另一个字符串。但这与你的问题无关
您的常量在此处不相关。您试图修改不应修改的字符串。文字字符串永远不应该被修改,这是导致崩溃的原因 p1
是指向常量数据的指针,而不是常量指针。此外,它还指向一个文本常量,该常量通常位于代码空间中,现代操作系统和处理器通常会防止代码试图修改代码空间
您不应该对它崩溃感到惊讶,但一般来说,行为是未定义的。@cnicutar-正是我需要的,谢谢您Much@Adel这是错误的。您是否可以更改“john”取决于实现。您不能依赖它,因此不应该使用它。p1
不必是只读变量(您只是无缘无故地添加了该限制),但*p1
是只读的。一个小小的星号可以在C中产生很大的不同!修改字符串文字是不正确的。因此,Seg错误是完全合理的。这不应该在那里崩溃-修复您的注释:)@bdonlan我修改了答案,指出崩溃是由于修改了指针指向的常数,感谢您的一个好观点。我的意思是,您有一个//崩溃
,在一行不应该崩溃的代码。@bdonlan哦,那!谢谢,我现在修好了:)哦,那部分是我的错!我应该像克拉希兹一样说得更清楚!
char * const p = "john";
char const * p = "john";
const char * p = "john";