问题描述
- 新手请教一个c的问题,关于指针赋初始值
- #include
int main()
{
char *p=NULL;
scanf(""%s""p);
printf(""%s""p);
return 0;
}
这段代码我在ios的终端下运行就提示Segmentation fault:11
但是不给p赋初值的话。。改称char *p;反而好使了。。为什么。。。
请教别人说是编译器的问题。能不能稍微详细的说一下为什么。。
解决方案
要先弄清楚scanf的参数用途,
这里scanf将要在p指定的地址上写入用户输入的字符串
操作系统装载程序的时候会将虚拟内存地址划分成多个区域,其中包括reserved readonly等是从低地址开始的也就是从0开始,这部分内存程序不能读写,如果试图读写就会出现segment fault
除了一些不能读写的区域外的很大部分是可以被读写。
所以如果指定了p=NULL肯定会出现错误。
但是如果不指定,那p的值由编译器决定,如果p刚好被赋值为可读写区域就不会报错,具体地址可以用printf打印出来看一下。
具体可以看看《链接装载与库》这本书,第十章第一节就讲的这个问题
解决方案二:
好使也不能这样用啊?
与编译器相关的行为。
解决方案三:
char *p=NULL;,指针 p 没有初始化,需要先分配内存空间。
改为 char *p; 是随机值,危害可以更大。
解决方案四:
无论如何,都需要给p申请存储空间。
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
解决方案五:
p 没有地址空间。char *p 其实 p='' 是有地址空间的
解决方案六:
要先给p分配空间才行,例如 char p = (char)malloc(80);
解决方案七:
去看看谭浩强的入门级C课本吧。
解决方案八:
char *p = NULL 賦初值的时候, 指针指向内存中0x0000000处,所指向的内存段为0, p因为是一个指针,也就是说指针必须指向一段字节数>0的内存, 而且p指向的是这段内存的首地址!!! 所以在scanf函数之前必须为p指向的内存块分配一定的内存空间 之后才能系统调用为这段内存填充字节; 而且在内存中NULL表示的是两段内存的截断,表示比如说两个字符串共同战友一段连续的内存,NULL表示两个字符串的截断; 这和字符串不同,因为再字符串数组中是以 ‘’作为一个字符串的结束的; 所以 初始化为NULL系统会出错;
不初始化会造成严重的后果, 在code_blocks dev 编译都不能达到预期的效果; 不初始化将导致p指针的值不确定, 导致内存重写, 内存溢出等很多严重问题; 所以慎用 !!
解决方案九:
char *p; 表示定义了一个字符指针,指向未知
向指向未知的地方写东西是不正确的。所以不要认为这叫“好使”。只是暂时恰好没有引起错误而已。定义了指针就要让他指向合法的可用的内存地址。
比如指向malloc返回的地址,或者指向某个数组等等