怎样避免指针变量未初始化带来的错误?

C语言 码拜 10年前 (2015-05-11) 1148次浏览 0个评论
 

书上有这么一道题:下列程序问题,体会使用指针时应该如何避免这个问题?

#include <malloc.h>
using namespace std;

int main(int argc, char* argv[])
{
        int *p;
	//int *p=(int *)malloc(4);   //用动态内存分配函数来初始化么?
	//int *p=new int;
	*p=9;
	cout<<"The value a p:"<<*p<<endl;

	return 0;
}

两个注释是我的方法,就是声明指针的时候给他分配空间,而不是它默认的oxccccccc.

1分
Windows下可以用
IsBadReadPtr(), IsBadWritePtr(), IsBadCodePtr(), IsBadStringPtr()
判断
1分
定义的时候就初始化清空!这个是个编程好习惯!
1分
int* p = NULL;

引用 楼主 zhang5476499 的回复:

书上有这么一道题:下列程序问题,体会使用指针时应该如何避免这个问题?

#include <malloc.h>
using namespace std;

int main(int argc, char* argv[])
{
        int *p;
	//int *p=(int *)malloc(4);   //用动态内存分配函数来初始化么?
	//int *p=new int;
	*p=9;
	cout<<"The value a p:"<<*p<<endl;

	return 0;
}

两个注释是我的方法,就是声明指针的时候给他分配空间,而不是它默认的oxccccccc.

1分
必须初始化啊
不初始化,程序不稳定
1分
2种方法都是可以的。
1分
顺便说下,默认的0xCCCCCCCC,这个不是默认的,而是VC的调试版本为了便于你跟踪野指针特意帮你初始化的。在Release中就不是了。
1分
引用 6 楼 caozhy 的回复:

顺便说下,默认的0xCCCCCCCC,这个不是默认的,而是VC的调试版本为了便于你跟踪野指针特意帮你初始化的。在Release中就不是了。

也只是vc而已!其他环境不一定的,系统爱给多少就给多少了!

1分
引用 7 楼 max_min_ 的回复:
Quote: 引用 6 楼 caozhy 的回复:

顺便说下,默认的0xCCCCCCCC,这个不是默认的,而是VC的调试版本为了便于你跟踪野指针特意帮你初始化的。在Release中就不是了。

也只是vc而已!其他环境不一定的,系统爱给多少就给多少了!

是的。所以提醒lz注意下。

1分
pclint检查一下基本上就看出来了
1分
自己小心 
1分
安全起见,确保已经初始化。 
1)用NULL初始化。
#include <malloc.h>
int main(int argc, char* argv[])
{
     int* p = NULL;
     。。。。。
     if(p){
        ……
     }
     return 0; 
}
2)用有效地址初始化
2.1)变量地址初始化。
#include <malloc.h>
int main(int argc, char* argv[])
{
     int a;
     int* p =&a;
     if(p){
          ……
          free(p);
     }
     return 0; 
}
2.2) 为指针,分配内存。
#include <malloc.h>
int main(int argc, char* argv[])
{
     int* p = malloc(sizeof(int));
     if(p){
          ……
          free(p);
     }
     return 0; 
}

实际上有点多余。

1分
变量都要初始化一下。。。。。。。。。

养成好习惯。。

int *p=NULL;

1分
ls正解,定义指针赋空比较好,然后用之前用if语句进行判断。
1分
我告诉LZ正规公司的方法:
1. 编译后的代码用静态工具检查一下, 这类工具包括pclint, coverity等等
2. 其实现代编译器也都会对这类错误告警, 编译时除了error必须修改外, 所有的warning也尽量做到清0
3. 写测试用例, 使用gcov等工具检查主要代码都被覆盖到

1分
变量初始化是习惯,你要适应他
引用 2 楼 max_min_ 的回复:

定义的时候就初始化清空!这个是个编程好习惯!

嗯,明白,就是不知道初始化为什么较好而已,难道是楼下提供的初始化为NULL?

引用 3 楼 turingo 的回复:

int* p = NULL;

Quote: 引用 楼主 zhang5476499 的回复:

书上有这么一道题:下列程序问题,体会使用指针时应该如何避免这个问题?

#include <malloc.h>
using namespace std;

int main(int argc, char* argv[])
{
        int *p;
	//int *p=(int *)malloc(4);   //用动态内存分配函数来初始化么?
	//int *p=new int;
	*p=9;
	cout<<"The value a p:"<<*p<<endl;

	return 0;
}

两个注释是我的方法,就是声明指针的时候给他分配空间,而不是它默认的oxccccccc.

嗯嗯,我也体验过了如果指针不初始化会引起程序崩溃的。

引用 6 楼 caozhy 的回复:

顺便说下,默认的0xCCCCCCCC,这个不是默认的,而是VC的调试版本为了便于你跟踪野指针特意帮你初始化的。在Release中就不是了。

谢了。

1分
本帖最后由 max_min_ 于 2013-12-07 10:06:14 编辑
引用 16 楼 zhang5476499 的回复:
Quote: 引用 2 楼 max_min_ 的回复:

定义的时候就初始化清空!这个是个编程好习惯!

嗯,明白,就是不知道初始化为什么较好而已,难道是楼下提供的初始化为NULL?

一般都是初始化为NULL,你就知道它指向的地址了!可以后面作判断使用!
如果没有初始化的话,它的指向的位置就是不可预知了的!就是后面赋值操作,你也不一定知道成功与否

引用 14 楼 truelance 的回复:

我告诉LZ正规公司的方法:
1. 编译后的代码用静态工具检查一下, 这类工具包括pclint, coverity等等
2. 其实现代编译器也都会对这类错误告警, 编译时除了error必须修改外, 所有的warning也尽量做到清0
3. 写测试用例, 使用gcov等工具检查主要代码都被覆盖到

哇,第一次听到这些词,学习了。本人大二,应该还有时间来优化自己的编程习惯吧。

2分
  很多公司上班要求warning必须为零的,楼主毕业了就知道了,还是养成好习惯吧。
2分
引用 11 楼 lm_whales 的回复:

安全起见,确保已经初始化。 
1)用NULL初始化。

int main(int argc, char* argv[])
{
     int* p = NULL;
     。。。。。
     if(p){//注意检测是否有效的指针。
        ......
     }
     return 0; 
}

2)用有效地址初始化
2.1)变量地址初始化。

//这个地方写错了,改成这样:
int main(int argc, char* argv[])
{
     int a;
     int* p =&a;
       ......
     
     return 0; 
}

2.2) 为指针,分配内存。

#include <malloc.h>
int main(int argc, char* argv[])
{
     int* p = malloc(sizeof(int));
     if(p){//可能也需要检测,甚至还要处理异常,不过内存耗尽,几乎也不能做什么了。
          ......
          free(p);
     }
     return 0; 
}

实际上有点多余。

另外,函数调用时,要保证指针参数是有效地址。

1分
引用 1 楼 caozhy 的回复:

Windows下可以用
IsBadReadPtr(), IsBadWritePtr(), IsBadCodePtr(), IsBadStringPtr()
判断

MSDN上有说:
IsBadReadPtr Function

Verifies that the calling process has read access to the specified range of memory.

Important  This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use. For more information, see Remarks on this page.

尝试过这些函数,实际作用不大。还不如断言机制。

1分
1. 要么,不使用指针。大多数情况下,在C++中,数组可以用vector来替代,字符串指针可以用string替代,等等等。除非有特殊目的,C++标准库完全可以满足你的需求。

2. 要么,自己把指针操作(内存管理)封装起来。
C++中的标准STL容器不都把内存管理封装的很好嘛。

1分
引用 6 楼 caozhy 的回复:

顺便说下,默认的0xCCCCCCCC,这个不是默认的,而是VC的调试版本为了便于你跟踪野指针特意帮你初始化的。在Release中就不是了。

学习了。

1分
程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。
1分
每天回帖即可获得10分可用分!
引用 27 楼 sugar13 的回复:

每天回帖即可获得10分可用分!

是么????

引用 26 楼 zhao4zhong1 的回复:

程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

嗯。

5分
引用 28 楼 zhang5476499 的回复:
Quote: 引用 27 楼 sugar13 的回复:

每天回帖即可获得10分可用分!

是么????

不知道,但是提交回复的按钮的右边不是有一牌小字么:
(Ctrl+Enter) 每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分 你还可以输入10000个字符


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明怎样避免指针变量未初始化带来的错误?
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!