关于C++野指针的问题

在做C++开发时,总避免不了与指针打交道,代码一多,野指针就成了一个问题!就此,我专门研究了一下野指针,总结其规律,仅供大家参考一下。

我们知道,代码所获得的内存地址是系统所提供的虚拟内存地址,其与真正的物理内存地址之间存在着映射关系,也就是所谓的内存管理机制。对每一个程序而言,都会的自己的独立的内存空间(4G)。

考察下面两段代码:

/*

test1:file1.cc

野指针存在于main函数内,编译能通过但会出现段错误

*/

include<iostream>

using std::cout;

using std::endl;

int main()

{

    int* p1;

    cout<<*p1<<endl;

return 0;

}

/*

test2:file2.cc

野指针存在于一般函数内,编译能通过并且会输出

该野指针所指向的值

*/

include<iostream>

using std::cout;

using std::endl;

void test()

{

   int* p2;

   cout<<*p2<<endl;

}

int main()

{

  test();

}

为什么野指针在mian函数中不能输出其指向的值而在一般函数中却可以呢?很奇怪吧!!这其实一点都不奇怪!再来考察一下,这两个野指针的地址值。发现p1=NULL;而p2=0xffde38(可能会是其他的),所以想要获得指向NULL的值心定是会出现错误的。

那有人会问,为什么p2所指向的值为什么可以输出呢?为解答这个问题,我们再来看个例子。

/*

test3:file3.cc

野指针存在于一般函数中,但是给它随意赋个地址值0xddff45;

能通过编译但也会出现错误

*/

#include<iostream>

using std::cout;

using std::endl;

void test()

{

    int* p3=(int*)0xddff45;

   cout<<*p<<endl;

}

int main()

{

     test();

return 0;

}

按照前面所说的,不给野指针赋值会得到一个野地址,随意赋个值也同样是个野地址值,那为什么一个能输出其所指向的值而另一个却不能呢?

这是因为,一个是系统给分配的,虽然也是个随意的地址,但是仍然是处在自己的独立内存内间里的,也就是说到最后映射时,不会映射到其他程序

所占用的地址空间去。而人工随意分配的话,一般都不会在自己的独立内存空间里面的,映射之后会跑到其他程序所占用的存在中去。

由此可以,野指针其实不像平常我们想的那样可怕,只要它还处在自己的空间里就是良性的。当然,这并不是说鼓励大家写代码时都是野指针,一般来讲,当

定义一个指针时,最好将其初始化为NULL;这样会好很多。

### 三级标题:C++ 中的指针概念 在 C++ 中,指针(wild pointer)是指向不可用内存区域的指针。这类指针通常出现在以下几种情况: - **未初始化的指针**:指针变量在定义时没有被赋予一个明确的地址值,此时它的内容是随机的,可能指向任何位置[^3]。 - **已经释放的内存**:当通过 `delete` 或 `free` 释放了动态分配的内存后,如果未将指针设置为 `nullptr` 或 `NULL`,则该指针仍然指向原来的内存地址,但此时该地址已不再有效[^5]。 - **超出作用域的指针**:当指针所指向的对象在其作用域外被销毁,而指针依然保留着旧的地址值。 指针不同于空指针(`NULL` 指针),后者可以通过简单的条件判断来避免访问错误,而指针由于其指向的是垃圾内存区域,一旦尝试访问,往往会导致不可预测的行为,甚至程序崩溃。 ### 三级标题:如何避免指针 为了避免指针带来的问题,可以采取以下措施: - **初始化指针**:在声明指针变量时,应立即对其进行初始化,即使不知道具体的地址值,也应当将其初始化为 `nullptr` 或 `NULL`[^4]。 ```cpp int *ptr = nullptr; // 初始化为空指针 ``` - **检查指针有效性**:在使用指针操作之前,确保指针不是 `nullptr` 或 `NULL`,并且确实指向了有效的内存空间[^4]。 ```cpp if (ptr != nullptr) { // 安全地使用 ptr } ``` - **释放内存后重置指针**:在调用 `delete` 或 `free` 之后,立即将指针设置为 `nullptr` 或 `NULL`,以防止后续误用[^5]。 ```cpp delete ptr; ptr = nullptr; // 避免悬空指针 ``` - **验证内存分配结果**:对于通过 `new` 或 `malloc` 分配的内存,在使用前应当检查返回的指针是否为 `nullptr` 或 `NULL`,这表明分配失败。 ```cpp int *array = new (std::nothrow) int[10]; // 使用nothrow保证分配失败时不抛出异常 if (array == nullptr) { // 处理分配失败的情况 } ``` - **清理数组或结构体数据**:对于栈上的数组或结构体,在使用前可以用 `memset` 将其初始化为零,减少未初始化数据的风险[^4]。 ```cpp int arr[10]; memset(arr, 0, sizeof(arr)); // 使用 memset 将数组的所有元素置为 0 ``` 以上策略能够有效地帮助开发者规避指针问题,从而提高程序的安全性和稳定性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值