2 qq 24129549 qq_24129549 于 2014.12.02 15:57 提问

新手请教一个c的问题,关于指针赋初始值
c

#include
int main()
{
char *p=NULL;
scanf("%s",p);
printf("%s",p);
return 0;
}
这段代码我在ios的终端下运行就提示Segmentation fault:11
但是不给p赋初值的话。。改称char *p;反而好使了。。为什么。。。
请教别人说是编译器的问题。能不能稍微详细的说一下为什么。。

9个回答

piaobotudou
piaobotudou   2014.12.02 17:39
已采纳

要先弄清楚scanf的参数用途,
这里scanf将要在p指定的地址上写入用户输入的字符串
操作系统装载程序的时候会将虚拟内存地址划分成多个区域,其中包括reserved, readonly等是从低地址开始的也就是从0开始,这部分内存程序不能读写,如果试图读写就会出现segment fault
除了一些不能读写的区域外的很大部分是可以被读写。
所以如果指定了p=NULL肯定会出现错误。
但是如果不指定,那p的值由编译器决定,如果p刚好被赋值为可读写区域就不会报错,具体地址可以用printf打印出来看一下。
具体可以看看《链接装载与库》这本书,第十章第一节就讲的这个问题

qq_24129549
qq_24129549 谢谢了,知道大致的意思了
大约 3 年之前 回复
zjtyuqilin
zjtyuqilin   2014.12.02 16:06

好使也不能这样用啊?
与编译器相关的行为。

qq_24129549
qq_24129549 正常不是应该char *p=NULL;的么。。但是给他一个空指针反而运行错误了。。好挣扎啊。。已经迷糊了
大约 3 年之前 回复
91program
91program   Ds   Rxr 2014.12.02 16:52

char *p=NULL;,指针 p 没有初始化,需要先分配内存空间。
改为 char *p; 是随机值,危害可以更大。

91program
91program 回复qq_24129549: 例如,使用 malloc 来为指针分配一指定大小的内存空间,在此内存空间不再使用时,必须要释放分配来的内存空间。否则,会产生内存泄露。释放使用函数:free。
大约 3 年之前 回复
91program
91program 回复qq_24129549: p=null 不就是将 p 指向零地址,零地址是不能操作的,系统限制。指针要想正确使用,就必须在定义后为它分配内存空间。
大约 3 年之前 回复
qq_24129549
qq_24129549 为什么p=null了还没有初始化啊
大约 3 年之前 回复
zhao4zhong1
zhao4zhong1   Rxr 2014.12.02 17:34

无论如何,都需要给p申请存储空间。
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

hpm1314
hpm1314   2014.12.02 20:16
p 没有地址空间。char *p    其实 p=''  是有地址空间的
turingo
turingo   Rxr 2014.12.03 18:20

要先给p分配空间才行,例如 char p = (char)malloc(80);

sunwu_siat
sunwu_siat   2014.12.04 18:32

去看看谭浩强的入门级C课本吧。

u012823258
u012823258   2014.12.06 11:32

char *p = NULL 賦初值的时候, 指针指向内存中0x0000000处,所指向的内存段为0, p因为是一个指针,也就是说指针必须指向一段字节数>0的内存, 而且p指向的是这段内存的首地址!!! 所以在scanf函数之前必须为p指向的内存块分配一定的内存空间, 之后才能系统调用为这段内存填充字节; 而且在内存中NULL表示的是两段内存的截断,表示比如说两个字符串共同战友一段连续的内存,NULL表示两个字符串的截断; 这和字符串不同,因为再字符串数组中是以 ‘\0’作为一个字符串的结束的; 所以 初始化为NULL系统会出错;

不初始化会造成严重的后果, 在code_blocks, dev 编译都不能达到预期的效果; 不初始化将导致p指针的值不确定, 导致内存重写, 内存溢出等很多严重问题; 所以慎用 !!

starytx
starytx   Rxr 2014.12.09 15:30

char *p; 表示定义了一个字符指针,指向未知
向指向未知的地方写东西是不正确的。所以不要认为这叫“好使”。只是暂时恰好没有引起错误而已。定义了指针就要让他指向合法的可用的内存地址。
比如指向malloc返回的地址,或者指向某个数组等等

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!