Sam*_*Sam 1 c assembly c-strings
我对这个简单的事情进行了尴尬的斗争,因为这是段错误:
#include <stdio.h>
int main()
{
char *test = "this is a string";
test[0] = 'q';
printf(test);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但这不是:
#include <stdio.h>
int main()
{
char test[] = "this is a string";
test[0] = 'q';
printf(test);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
查看程序集后,我注意到在第一种情况下,文字"this is a string"是在 中声明的.rodata,因此这解释了段错误。但在第二种情况下,字符串根本不在程序集中,因此我假设它是通过 .data 部分链接为可写的。为什么会有这种行为差异?这很明显吗?我很愚蠢吗?
这很明显吗?应该是因为它是C语言的一个重要特性:即使由于历史原因没有声明为const,字符串文字也是不可变的。让我们仔细看看:
char *test = "this is a string";
Run Code Online (Sandbox Code Playgroud)
这(错误地)声明了一个指向 const 字符数组的非常量指针。从那时起,通过该指针更改字符会显式调用未定义的行为。这里你遇到了一个段错误,但是编译器可以自由地忽略该尝试,退出程序而不显示任何消息,甚至<在此处输入你最糟糕的噩梦> ...
一个像样的编译器应该警告你这一点(警告不能被忽略......)并且正确的语法是const char *test = "this is a string";.
char test[] = "this is a string";
Run Code Online (Sandbox Code Playgroud)
这(正确地)声明了一个字符数组,并通过字符串文字的副本初始化其内容。如果您提供初始值设定项文字字符串并使用初始值设定项的大小作为数组的大小,该语言足够允许您给出空大小。从那时起,更改数组的字符就是合法的操作。
你应该记住什么:
| 归档时间: |
|
| 查看次数: |
81 次 |
| 最近记录: |