未初始化指针问题

流比 2011-08-20 04:17:53
新手提问
《C和指针》书上说

int *a
...
*a = 12

这样写声明一个变量,但未对指针初始化

如果指针是函数的形参,比如

void func(int *a)
{
(* a) = 12;//这样操作有无问题?
}





...全文
881 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
modicum_ck 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 finewind 的回复:]
楼主,你应该理解清楚什么是指针:通俗的讲,指针是一个地址,指针的初始化就是让指针指向一个确定的地址。*是指针的解引用符,意思是取指针指向的地址里的数据。
因此,int a;
int *p = &a;
// 这里是初始化,表示的是指针初始化为a的地址,实际相当于 int *p; p = &a;
*p = 10;
// 这是表示对指针解引用,想p所指向的地址……
[/Quote]

++
w346581442 2011-08-21
  • 打赏
  • 举报
回复
书上说这是一个极为常见的错误
w346581442 2011-08-21
  • 打赏
  • 举报
回复
你没有细看那书,我也在看,虽然我看了很多遍,书上就说它是有问题的
smart_fish8 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hua_yang 的回复:]
有问题

应该先判断指针是否分配了空间,否则操作非常危险
if(NULL != a)
{
*a = 12;
}
[/Quote]这可不一定,你要看你传过来的指针是不是一个合法的地址,不能把野指针传过来。
tyr 2011-08-21
  • 打赏
  • 举报
回复
第一个声明一个整型指针变量,没有给其初始化一个有效地址就修改其值,可能改到系统用的内存区域,导致崩溃等(具体看运气)

第二个的形参会在函数所在的栈内存中分配个临时地址,赋予实参后会重新指向实参指针的地址,其本身会随着函数的生命周期自动销毁。是否危险看其外部的实参了,可能如前面的第一种情况。
低头思蚊香 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xin_wu_hen 的回复:]
上面的有问题,下面没有问题。
[/Quote]
我也觉得lz第一个有问题,第二个没问题,第一个真的是书上说的?
Alexander 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 saishow 的回复:]

“野指针”不是NULL指针,是指向“垃圾”内存(不可用内存)的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if无法判断一个指针是正常指针还是“野指针”。有个良好的变成习惯是避免“野指针”的唯一方法。

野指针的成因主要有三种:
一、指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变……
[/Quote]
抱歉,阁下给的第二个例子一般情况下是可以正确运行的。

阁下对于“变量的生命期”好像有些误解。变量的生命期是指变量自身存在区间,并不会影响到它所指向的内在空间。
以你的程序为例:变量a的生命期结束指的是1、a这个符号不再有效,2、OS不会再对a所指向的地址进行保护。
可见,除非是p->Func之前该内存碰巧被其它进程修改这种极其偶然的状况,否则p->Func还是可以正常执行的。

另外,“野指针”指的并不是它指向不可用内存,而是它所指向的内存地址不确定,而且由于指向内存没有被OS保护,导致其内容不确定。这种不确定性通常不是我们程序所需要的。(由于指向的地址不确定,假如指向的地址是被其它进程锁定的,就会导致程序崩溃)
modicum_lf 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hua_yang 的回复:]
有问题

应该先判断指针是否分配了空间,否则操作非常危险
if(NULL != a)
{
*a = 12;
}
[/Quote]

++

saishow 2011-08-21
  • 打赏
  • 举报
回复
“野指针”不是NULL指针,是指向“垃圾”内存(不可用内存)的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if无法判断一个指针是正常指针还是“野指针”。有个良好的变成习惯是避免“野指针”的唯一方法。

野指针的成因主要有三种:
  一、指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
  二、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。别看free和delete的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。例:
  #include <stdio.h>
  #include <string.h>
  #include <malloc.h>
  void main(void)
  {
  char *p = (char *) malloc(100);
  strcpy(p, "hello");
  free(p); // p 所指的内存被释放,但是p所指的地址仍然不变
  if(p != NULL) // 没有起到防错作用
  strcpy(p, “world”); // 出错(注意:编译链接是不会出错的)
  for(i=0;i<5;i++) //i=5后为乱码
  printf("%c",*(p+i));
  printf("\n");
  }
  另外一个要注意的问题:不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。
  三、指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:
  class A
  {
  public:
  void Func(void){ cout << “Func of class A” << endl; }
  };
  void Test(void)
  {
  A *p;
  {
  A a;
  p = &a; // 注意 a 的生命期 ,只在这个程序块中(花括号里面的两行),而不是整个test函数
  }
  p->Func(); // p 是“野指针”
  }
  函数 Test 在执行语句 p->Func()时,对象 a 已经消失,而 p 是指向 a 的,所以 p 就成了“野指针” 。
chen_yuan 2011-08-21
  • 打赏
  • 举报
回复
对变量赋值,变量一定要有内存空间,不能对空地址进行赋值操作。

这个问题要看你程序的上下文了,如果有内存空间,就没有问题;
如果是空指针,就不行了。
qq120848369 2011-08-21
  • 打赏
  • 举报
回复
指针存的是地址,*p是访问那个地址的内存。

int *p; p里存的是随机数,*p访问就不知道访问到哪里了,就是非法的了。
androidrobot1 2011-08-21
  • 打赏
  • 举报
回复
函数这么写没什么问题,c中其实只有值传递,所谓的地址传递也是值传递,只是这值是一地址而已。在对a做*a操作时,主要看a所指向的地址在那里,只要是代码区得地址,就不能修改,其他地方(全局区,堆,栈)的地址
都可以做*a。
CJacky++ 2011-08-20
  • 打赏
  • 举报
回复
指针是C程序员的骄傲,也是噩梦。。。。。。
AnYidan 2011-08-20
  • 打赏
  • 举报
回复
lz 的题目就说明白了

没初始化就解引用,一定有问题
如果初始化,一般没有问题
绿野耕夫 2011-08-20
  • 打赏
  • 举报
回复
楼主,你应该理解清楚什么是指针:通俗的讲,指针是一个地址,指针的初始化就是让指针指向一个确定的地址。*是指针的解引用符,意思是取指针指向的地址里的数据。
因此,int a;
int *p = &a;
// 这里是初始化,表示的是指针初始化为a的地址,实际相当于 int *p; p = &a;
*p = 10;
// 这是表示对指针解引用,想p所指向的地址写入10

第2个是关于函数调用,一个函数在那里,并不会自己运行,只有你去调用它它才会运行。在函数调用发生时,C语言实际做的是用实际参数代替形参。
int *p;
func(p); // 在这里(函数调用)的时候,实际相当于有如下过程:int *a; a = p;(实参代替形参); *a = 10; 因此,这样操作是否有问题,关键在于p(实参)本身是否有问题。如果p本身指向了一个确切的地址,则a=p也使a(形参)实际指向了一个确切的地址,如果p本身没初始化,那么a = p 也使a实际指向了一个未初始化的地址。
xin_wu_hen 2011-08-20
  • 打赏
  • 举报
回复
上面的有问题,下面没有问题。
hua_yang 2011-08-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 duguyixiaono1 的回复:]
只要你传入函数的实參已经初始化就没问题

属于地址传递,函数参数传递方式分为值传递和地址传递
[/Quote]

没有空间,即使初始化,例如:在外面初始化成NULL也是不行的
duguyixiaono1 2011-08-20
  • 打赏
  • 举报
回复
只要你传入函数的实參已经初始化就没问题

属于地址传递,函数参数传递方式分为值传递和地址传递
hua_yang 2011-08-20
  • 打赏
  • 举报
回复
有问题

应该先判断指针是否分配了空间,否则操作非常危险
if(NULL != a)
{
*a = 12;
}
atzai 2011-08-20
  • 打赏
  • 举报
回复
应该没问题

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧