分段引用char数组时出错

#include int main(void) { char * p= "strings are good"; printf("%s",*p); return 0; } 

有人可以告诉我为什么我在这里得到分段错误?

有人可以告诉我为什么我在这里得到分段错误?

C11:7.21.6格式化输入/输出function:

如果转换规范无效,则行为未定义.282)如果任何参数不是相应转换规范的正确类型,则行为未定义。

3.4.3

1使用不可移植或错误的程序结构或错误数据时, 未定义的行为行为,本国际标准不对此作出任何规定。

2 注意可能的未定义行为包括完全忽略不可预测的结果,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的文档方式行为,终止翻译或执行(与发出诊断信息)。

*pchar类型。 %s期望char *类型的参数。 这将调用未定义的行为 。 在这种情况下,一切都可能发生 有时您可能会得到预期的结果,有时则不会。 这也可能导致程序崩溃或分段错误(这种情况就是这种情况)。

对于%s ,您需要传递sting / literal的起始地址。

更改

 printf("%s",*p); 

 printf("%s",p); 

这是问题所在:

 printf("%s",*p); 

printf将解析const char *格式字符串,在您的情况下: "%s" ,并推断除格式之外的第一个参数也将是char *
现在,因为你取消引用指针,你传递一个char( char ,没有*
现在,如果将char的大小与char 指针的大小进行比较:

 printf("%d vs %d\n", sizeof(p), sizeof(*p)); 

你会看到一个char指针是4(或64位的8)乘以char的大小。
考虑一下你实际上在做什么,强制printf将char的值强制转换为指针,然后使用该指针读取字符串:

 const char *p = "foobar"; printf("%p\nWhereas you wanted: %p\n", (void *) *p, (void *) p); 

输出:

 0x66 //not a valid pointer, too small Whereas you wanted: 0x80485c8 //<-- actual address may vary 

解决方案:

 printf("%s\n", p); 

不要取消引用指针,只是按原样传递它。
只是一个小技巧:学会喜欢存储类修饰符const 。 在这种情况下,这是一个有用的提醒:

 char *p; //some code p = "a string"; //more code, or passing p to a function that attempts to do: p[0] = 'A';//ERROR!! 

鉴于:

 const char *p;//I can SEE p points to a constant p = "a string"; p[0] = 'A';//error, the declaration of p tells me why 

const是一个视觉提示,无论你要用p做什么,你都应该记住它指向一个常数 ,并且无法编辑该值。

您在printf格式的输出中将单个字符串作为字符串类型(%s)传递。 将其更改为p