分段错误和char指针和int ponter

时间:2015-11-01 05:03:44

标签: c++ pointers

code1:



char *pc = "abc";     
cout<<*pc<<endl;

码2:



int *pi = 10 ;
cout<<*pi<<endl;

为什么 code1 警告消息提示为“警告:不推荐将字符串常量转换为'char *'”;但 code2 提示错误 消息为“错误:从'int'无效转换为'int *'”。

【Q1】 在我看来,它们都是不匹配的,但为什么一个人会收到警告而另一个人会收到错误?

当我尝试解决这个问题时:

code3:



int *pi = (int*)10 ;  //compile correctly without error
cout<<*pi<<endl;      //get "segmentation fault"

码4:



char *pc = (char*)"abc";  //compile without warning    
cout<<*pc<<endl;         // output 'a'

【Q2】 为什么 cout&lt;&lt; * pi&lt;&lt;在code3中的endl; 获得分段错误并且 cout&lt;&lt; * pc&lt;&lt; code4中的endl 是否正确运行?

这似乎是一个受欢迎的问题,但对差异的解释很少。有人可以帮帮我吗?

提前致谢。

3 个答案:

答案 0 :(得分:2)

  1. 尝试:

    const char *pc = "abc";     
    cout << pc << endl;
    
  2. 尝试:

    int pi = 10;
    cout << pi << endl;
    
  3. 在上面的情况1中,字符串文字的类型为const char *

    在第2种情况下,你声明的不是整数,而是整数指针并将ADDRESS 10指定给指针,然后尝试取消引用它(实际上你试图访问内存地址10的数据,你可能不会无法访问,这就是你遇到崩溃的原因)

答案 1 :(得分:0)

虽然危险的语法可能,这里foo指向内存中的有效位置 - 它是指向“abc”开头的字符指针(也称为“a”):

char *foo = "abc";

但是在这里:

int *pi = (int*)10 ;  //compile correctly without error
cout<<*pi<<endl;

pi指向内存地址10,这是好的,直到你尝试顺从 - 这是一个很大的禁忌,因为你的程序无法访问该内存。

答案 2 :(得分:0)

char *pc = "abc";

&#34; ABC&#34;这就是所谓的字符串文字。它可能不会像您所知存储在内存中,并且可能无法更改。试着,例如

pc[1] = 'k';

会产生不可预测的结果,很可能会导致程序崩溃,因为无法写入该位置。

编译器警告告诉您正在指定一个指向值的指针,该指针不能或不应该更改为允许您更改值的指针。这里的快速解决方法是告知编译器您不会尝试更改&#34; abc&#34;如果你尝试,请接受编译器的打击。

const char *pc = "abc";

写入pc引用的内存现在将生成编译器警告,但比编写无效内存并做一些奇怪的事情更好。

这是一个警告,而不是一个错误,因为有大量的古代代码完全执行这种风险的常量 - &gt;非常量赋值但从不尝试写入不可写的位置,如果这样,将停止编译是一个错误。现在编译器只是标记问题并建议您修复它。

此代码:

char *pc = (char*)"abc";  
cout<<*pc<<endl;         

不会崩溃,或以其他方式表现出不良行为,因为持有&#34; abc&#34;是可读的。

char *pc = (char*)"abc";  
cin >>*pc;         
如果不立即致命,那将是非常糟糕的。

另一方面,

int *pi = 10 ;

有点不同。它生成一个指向内存位置10的整数的指针,这几乎肯定是错误的。虽然char *pc = "abc";存在风险,但尝试使用尚未分配给程序的内存位置是不好的,可能是致命的。你希望它是致命的,因为替代品是一个不那么有趣的游戏&#34; Dude,我的数据在哪里?&#34;指针不是整数,无论​​你被告知什么,这产生错误迫使程序员至少在做一些愚蠢的事情之前思考。

驱动程序和嵌入式编程中存在例外,其中直接硬件访问很常见,但这些是使用强制转换和其他技巧指定的,以确保编译器知道您正在做什么,并且在指定地址确实存在可访问的内容。正是你在这里做的:

int *pi = (int*)10 ;

但是当你尝试打印它时程序会崩溃,因为没有任何东西可以分配,并且程序可以在地址10中读取。正如你所看到的那样,这被认为是一个错误。你既不能读也不能写,所以它不会得到编译器为可读但不可写的&#34; abc&#34;提供的条件传递。