用指针修改字符串 [英] Modify a string with pointer

查看:78
本文介绍了用指针修改字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这两个代码要改变字符'4'

int main(int argc, char *argv[]){   
       char *s = "hello";   
       *(s+2)='4';
       printf( "%s\n",s);
       return 0;     
    }

运行时出现分段错误,而运行时出现分段错误:

When I run this I get segmentation fault while when I run this:

int main(int argc, char *argv[]){   
   char *s = argv[1];   
   *(s+2)='4';
   printf( "%s\n",s);
   return 0;     
}

我知道还有其他方法可以做到这一点.这两个程序有什么区别?

I know that there are other methods to do this. What is the difference between the 2 programs?

推荐答案

在您的第一种情况下,您面临着 未定义行为通过尝试修改字符串文字.分段错误是 UB 常见的副作用之一.

In your first case, you're facing undefined behaviour by attempting to modify a string literal. A segmentation fault is one of the common side-effects of UB.

在您的代码中,

 char *s = "hello";

本质上是将字符串文字"hello"的起始地址放入s.现在,是否要修改 *s(或 *(s+n) 的内容,前提是 n 不越界),它实际上会尝试修改那个字符串文字.通常,字符串文字存储在只读存储器中,它们通常不允许被修改.引自 C11,第 6.4.5 章,字符串文字(强调我的)

essentially puts the starting address of the string literal "hello" into s. Now, is you want to modify the content of *s (or *(s+n), provided n does not go out of bounds), it will actually try to modify that string literal. As usually, the string literals are stored in the read-only memory, they are usually not allowed to be modified. Quoting from C11, chapter §6.4.5, String literals, (emphasis mine)

如果这些数组的元素具有适当的值,则未指定它们是否不同.如果程序尝试修改这样的数组,则行为未定义.

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

然而,在你的第二种情况下,你正在做

However, in your second case, you're doing

 char *s = argv[1];

argv[1] 的值放入 s 中.现在,s 指向 argv[1] 包含的 string.这里,argv[1](或者,argv[n],一般来说)的内容不是只读的,可以修改.所以,使用*s(或*(s+n),只要n不越界),就可以修改内容.

which is putting the value of argv[1] into s. Now, s points to the string contanied by argv[1]. Here, the contents of argv[1] (or, argv[n], to be general) is not read-only, it can be modified. So, using *s (or *(s+n), provided n does not go out of bounds), you can modify the contents.

这种情况是定义的行为,因为根据§5.1.2.2.2,程序启动

This case is defined behaviour, because as per §5.1.2.2.2, Program startup

参数argcargv以及argv数组指向的字符串应该可以被程序修改,并在程序启动和程序终止之间保留它们最后存储的值.

The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

因此,第二种情况是使用 argv[n] 时的特殊情况,根据 C 标准规则,可以修改.

So, the second case is a special case while using argv[n], which is by the C standard rules, modifiable.

这篇关于用指针修改字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆