我正在尝试调用以下代码,这会导致段错误。我了解这表明程序正在尝试访问它无权访问的内存。我看到*b = *c
行引起了问题,但是据我了解,这应该是有效的操作。#include
int main(int argc, char *argv[])
{
char *b = "defg";
char *c = "hijk";
printf("%c,%c", *b, *c);
fflush(stdout);
*b = *c;
return 0;
}
$ gcc -g -Wall test108b.c && ./a.out
$ ./a.out
d,hMemory fault(coredump)
更新:使用x[]
定义字符数组与使用指向字符串文字的指针有效!以下备用代码有效:
#include <stdio.h>
int main(int argc, char *argv[])
{
char b[] = "defg";
char c[] = "hijk";
char *bp = b;
char *cp = c;
while (*bp)
*bp++ = *cp++;
bp = b;
while (*bp)
printf("%c", *bp++);
return 0;
}
gcc -g -Wall test108b.c && ./a.out
hijk
有人知道为什么第二版代码有效而第一版无效吗?
您的第一行是一个错误:
char *b = "defg";
字符串文字是只读的,应该分配给const char*
指针以反映这一点。
如果要使用字符串初始化char
array(不是指针),则可以执行此操作,并且可以对其进行修改:
char b[] = "defg";
请注意,这是一个例外,仅适用于使用字符串文字进行初始化。这行不通:
char c[] = b;
String文字是只读的,除了字符数组的初始化外,但实际上情况要复杂一些。此行为取决于您的编译器和体系结构,但是对于gcc和x86,这似乎是该行为。我相信这是出于安全原因。过去曾经有一个标记来启用您想要的行为,但是该标记也已从gcc中删除。最好的选择是将数组初始化为char数组。
#include <stdio.h>
int main(int argc, char *argv[])
{
char b[] = "defg";
char c[] = "hijk";
printf("%c,%c", *b, *c);
fflush(stdout);
*b = *c;
char *bp = b;
#if 0
while (*b)
*b++ = *c++;
while (*bp)
printf("%c", *bp++);
#endif
return 0;
}
[另外,我怀疑这只是一个演示程序,用于显示您所询问的行为,但是复制字符串的最佳方法是使用libbsd库中的strlcpy之类的东西(如果您使用的是Linux)。它的null终止与安全性较低的同级strcpy和strncpy不同。
以下是一些有用的编译器标志:
如果出现此错误,此标志将警告您。
-Wwrite-strings
此标志将警告您比较字符串文字的内存地址。
-地址
希望有所帮助