在C中,可以在声明中使用字符串文字,如下所示:
char s[] = "hello";
Run Code Online (Sandbox Code Playgroud)
或者像这样:
char *s = "hello";
Run Code Online (Sandbox Code Playgroud)
那么区别是什么呢?我想知道在编译和运行时的存储持续时间实际发生了什么.
我对字符串文字的分配/存储感兴趣.
我确实在这里找到了一个有趣的答案,说:
定义内联字符串实际上是将数据嵌入程序本身并且无法更改(某些编译器通过智能技巧允许这样做,不要打扰).
但是,它与C++有关,更不用说它不打扰了.
我很烦.= d
所以我的问题是我的字符串文字保存在哪里以及如何保存?我为什么不试着改变呢?实施是否因平台而异?有没有人愿意详细说明"聪明的伎俩"?
考虑:
char amessage[] = "now is the time";
char *pmessage = "now is the time";
Run Code Online (Sandbox Code Playgroud)
我从C编程语言第2版中读到,上述两个陈述没有做同样的事情.
我一直认为数组是一种操作指针来存储一些数据的便捷方式,但显然情况并非如此...... C中数组和指针之间的"非平凡"差异是什么?
我可以'some'在MSVC生成的汇编代码中看到两个文字,但只有一个有clang和gcc.这导致完全不同的代码执行结果.
static const char *A = "some";
static const char *B = "some";
void f() {
if (A == B) {
throw "Hello, string merging!";
}
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释这些编译输出之间的差异和相似之处吗?为什么即使没有请求优化,clang/gcc也会优化某些内容?这是某种未定义的行为吗?
我还注意到,如果我将声明更改为下面显示的声明,则clang/gcc/msvc根本不会"some"在汇编代码中留下任何声明.为什么行为不同?
static const char A[] = "some";
static const char B[] = "some";
Run Code Online (Sandbox Code Playgroud) Size_t被定义为一个unsigned整数,但它的大小取决于你是在32位还是64位机器上.什么是正确和便携的打印方式size_t?
有人可以解释为什么这适用于指针:
char * str1;
str1 = "Hello1";
str1 = "new string";
// but not this
char str2 [] = "hello";
str2 = "four";
// or this
char str3 [];
str3 = "hello";
str3 = "hello";
Run Code Online (Sandbox Code Playgroud) C中字符串文字的类型是什么?是char *或const char *否const char * const?
那么C++呢?
这个问题可以作为所有常见问题的参考:
当我将数据复制/扫描到未初始化指针所指向的地址时,为什么会出现神秘崩溃或"分段错误"?
例如:
char* ptr;
strcpy(ptr, "hello world"); // crash here!
Run Code Online (Sandbox Code Playgroud)
要么
char* ptr;
scanf("%s", ptr); // crash here!
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写代码来反转字符串(我只是想在C编程和指针操作方面做得更好),但我无法弄清楚为什么我会遇到分段错误:
#include <string.h>
void reverse(char *s);
int main() {
char* s = "teststring";
reverse(s);
return 0;
}
void reverse(char *s) {
int i, j;
char temp;
for (i=0,j = (strlen(s)-1); i < j; i++, j--) {
temp = *(s+i); //line 1
*(s+i) = *(s+j); //line 2
*(s+j) = temp; //line 3
}
}
Run Code Online (Sandbox Code Playgroud)
它是第2行和第3行导致分段错误.我知道可能有更好的方法来做到这一点,但我有兴趣找出我的代码中特别导致分段错误的内容.
更新:我已根据要求包含了调用函数.
我在SO中看到了很多关于在C程序中获取分段错误的问题,我认为在这里引用这些是很好的,这是一些导致分段错误的问题.我的答案发布在下面.
正如在一些答案中所写,对于所有情况,行为都是未定义的,尽管许多人将它们视为 分段错误,因此这个问题是关于导致这种"症状"的原因.
在下面的例子中,当我运行程序时出现分段错误,你能确定原因吗?
1)
char *str = "foo";
str[0] = 'b'; // << Segfault hre
Run Code Online (Sandbox Code Playgroud)
2)
char str[] = "foo";
char *newStr = malloc(strlen(str));
strcpy(newStr, str);
free(newStr); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
3)
char *str = malloc(4 * sizeof(char));
str = "foo";
free(str); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
4)
char *str = malloc(4 * sizeof(char));
strcpy(str, "foo");
free(str);
if (str != NULL)
free(str); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
5)
char *str = "something and then foo";
printf("%s", str[19]); // …Run Code Online (Sandbox Code Playgroud)