C++中的野指针问题

2023-05-16

文章目录
1 C和C++中的野指针问题
1.1 野指针的概念
1.2 野指针的由来
1.3 杜绝野指针的基本原则
2 C和C++中的常见内存错误
2.1 常见内存错误
2.2 内存操作的基本规则
1 C和C++中的野指针问题
1.1 野指针的概念
野指针的概念:

指针变量中的值是非法的内存地址,进而形成野指针。
野指针不是NULL指针,是指向不可用内存地址的指针。
NULL指针并无危害,很好判断,也很好调试。
C语言中无法判断一个指针所保存的地址是否合法。
1.2 野指针的由来
如下情况可能导致野指针的出现:

局部指针变量没有被初始化。
指针所指向的变量在指针之前被销毁(返回局部变量和局部数组)。
使用已经释放过的指针。
进行了错误的指针运算。
进行了错误的强制类型转换。
野指针初探:

#include <stdio.h>
#include <malloc.h>


int main()
{
    int* p1 = (int*)malloc(40);
    int* p2 = (int*)1234567;//p2是一个野指针
    int i = 0;

    for(i=0; i<40; i++)
    {
        *(p1 + i) = 40 - i;//由于指针运算产生了野指针,改写了非法的内容
    }

    free(p1); 

    for(i=0; i<40; i++)
    {
        p1[i] = p2[i];//使用了已经释放的内存空间
    }

    return 0;
}


1.3 杜绝野指针的基本原则
基本原则:

绝不返回局部变量和局部数组的地址。
任何变量在定义后必须0初始化。
字符数组必须确认0结束符后才能成为字符串。
任何使用与内存相关的函数必须指定长度信息。
无处不在的野指针:

#include <stdio.h>
#include <string.h>
#include <malloc.h>

struct Student
{
    char* name;
    int number;
};

char* func()
{
    char p[] = "D.T.Software";

    return p;
}

void del(char* p)
{
    printf("%s\n", p);

    free(p);
}

int main()
{
    struct Student s;//由于没有初始化,产生野指针
    char* p = func();//产生了野指针

    strcpy(s.name, p); //使用野指针

    s.number = 99;

    p = (char*)malloc(5);

    strcpy(p, "D.T.Software");//产生内存越界,操作了野指针所指向的内存空间

    del(p);

    return 0;
}


内存错误是实际产品开发中最常见的问题,然而绝大多数的bug都可以通过遵循基本的编程原则和规范来避免。因此,在学习的的时候要牢记和理解内存操作的基本原则,目的和意义。

2 C和C++中的常见内存错误
2.1 常见内存错误
常见内存错误如下:

结构体成员指针未初始化。
结构体成员指针未分配足够的内存。
内存分配成功,但并未初始化。
内存操作越界。
常见内存错误1:

#include <stdio.h>
#include <malloc.h>

void test(int* p, int size)
{
    int i = 0;

    for(i=0; i<size; i++)
    {
        printf("%d\n", p[i]);
    }

    free(p);
}

void func(unsigned int size)
{
    int* p = (int*)malloc(size * sizeof(int));
    int i = 0;

    if( size % 2 != 0 )
    {
        return; 
    }

    for(i=0; i<size; i++)
    {
        p[i] = i;
        printf("%d\n", p[i]);
    }

    free(p);
}

int main()
{
    int* p = (int*)malloc(5 * sizeof(int));

    test(p, 5);

    free(p); 

    func(9);
    func(10);

    return 0;
}
/*
说明:两次释放同一个指针可能会让程序崩溃,double free or corruption (fasttop): 0x0977b008 ***
Aborted (core dumped)。
*/

常见内存错误2:

#include <stdio.h>
#include <malloc.h>

struct Demo
{
    char* p;
};

int main()
{
    struct Demo d1;
    struct Demo d2;

    char i = 0;

    for(i='a'; i<'z'; i++)
    {
        d1.p[i] = 0; 
    }

    d2.p = (char*)calloc(5, sizeof(char));

    printf("%s\n", d2.p);

    for(i='a'; i<'z'; i++)
    {
        d2.p[i] = i; 
    }

    free(d2.p);

    return 0;
}
// 说明:calloc申请出来的内存会被全部置0。


2.2 内存操作的基本规则
1.动态内存申请之后,应该立即检查指针值是否为NULL,防止使用NULL指针。

2.free指针之后必须立即赋值为NULL。

3.任何与内存操作相关的函数都必须带长度信息。


补充: int snprintf(char restrict buf, size_t n, const char restrict
format, …);函数说明:最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n的话…
基本功能: 将可变个参数(…)按照format格式化成字符串,然后将其复制到str中 (1) 如果格式化后的字符串长度 <
size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符(‘\0’); (2) 如果格式化后的字符串长度 >=
size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符(‘\0’),返回值为格式化后的字符串的长度。
char a[20]; i = snprintf(a, 9, “%012d”, 12345);[1] printf(“i = %d, a =
%s”, i, a); 输出为:i = 12, a = 00000001

4.malloc操作和free操作必须匹配,防止内存泄漏和多次释放。


内存错误的本质源于指针保存的地址为非法值:

指针变量未初始化,保存随机值;
指针运算导致内存越界。
内存泄漏源于malloc和free不匹配:

当malloc次数多于free时,产生内存泄漏;
当malloc次数少于free时,程序可能崩溃。
应对的措施:在哪个函数里申请就在哪个函数里释放,不要跨函数释放动态内存空间。
/**************************野指针产生的三种情况

C/C++中野指针产生的三种情况

 1、指针变量未初始化:

 任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气,此时若未初始化,则产生野指针。

 2、指针释放后未置空:

 有时指针在free或delete后未赋值 NULL,便会使人以为是合法的,此时指针指向一块未定义、未分配的内存。其实free和delete只是把指针所指的内存给释放掉,但并没有把指针本身干掉。指针指向的就是“垃圾”内存。所以释放后的指针应立即将指针置为NULL,防止产生“野指针”。

 3、指针操作超越变量作用域:

 不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中的野指针问题 的相关文章

  • MFC框架机制详细论述

    1 1 Windows消息机制要点 1 1 1 窗口过程 每个窗口会有一个称为窗口过程的回调函数 WndProc xff0c 它带有四个参数 xff0c 分别为 xff1a 窗口句柄 Window Handle 消息ID Message I
  • c#中WinForm中拖拽窗体实现移动功能(无边框模态窗体)

    在WindowsForm 应用程序中 如果将窗体的FormBorderStyle属性设置为none 这时 用鼠标拖拽窗体时就无法实现移动的功能了 xff0c 下面就是解决方案 在FormBordeStyle属性设置为none的窗体的后台代码
  • 关于SetCapture() 和 ReleaseCapture()的用法

    MSND中对SetCapture 函数的说明为 xff1a 该函数在属于当前线程的指定窗口里设置鼠标捕获 一旦窗口捕获了鼠标 xff0c 所有鼠标输入都针对该窗口 xff0c 无论光标是否在窗口的边界内 同一时刻只能有一个窗口捕获鼠标 如果
  • c# Invoke和BeginInvoke 区别详解

    Control Invoke 方法 Delegate 在拥有此控件的基础窗口句柄的线程上执行指定的委托 Control BeginInvoke 方法 Delegate 在创建控件的基础句柄所在线程上异步执行指定委托 以下为实际应用中碰到的问
  • WindowsAPI-Findwindow函数和FindWindowEx用法

    1 函数说明 FindWindow xff0c Win32 API函数 FindWindow函数返回与指定字符串相匹配的窗口类名或窗口名的最顶层窗口的窗口句柄 这个函数不会查找子窗口 2 函数原型 xff1a HWND FindWindow
  • 利用FindWindow和SendMessage进程通信

    利用FindWindow和SendMessage xff0c 特此记下 首先说FindWindow FindWindow返回与指定字符创相匹配的窗口类名或窗口名的最顶层窗口的窗口句柄 函数原型为 xff1a C 43 43 xff1a HW
  • vnc viewer,什么是vnc viewer

    在日常工作中 xff0c 经常会用到vnc xff0c 自然也会用到vncviewer xff0c 那你知道什么是vncviewer吗 xff1f 怎么使用vncviewer呢 xff1f 接下来让我们一起去看看吧 首先先让我们来看看一款v
  • 句柄的概念详解

    1 这里将句柄所能标识的所有东西 xff08 如窗口 文件 画笔等 xff09 统称为 对象 2 图中一个小横框表示一定大小的内存区域 xff0c 并不代表一个字节 xff0c 如标有0X00000AC6的横框表示4个字节 程序运行到某时刻
  • Server.Transfer 和 Response.Redirect 的用法

    在ASP NET中 xff0c 在后台传值方式目前大多都是用 Response Redirect 34 页面地址 34 来重定向页面的 xff0c 但是现在还有一种方式也可以达到重定向页面的作用 xff0c 而且在某些时刻会起到一种很棒的效
  • WebForm连接数据库实例

    登录页面 xff1a 用户名文本框 密码文本框 登录按钮 当用户名密码输入正确 xff0c 点击确定可以跳转到下一个页面 我们需要先引入命名空间 xff1a using System Data using System Data SqlCl
  • ASP.NET WebForm和Mvc开发的比较

    在初步了解MVC后 xff0c 发现很多人对于MVC和三层架构开发概念上会有很大的混淆 xff0c 所以把这两天的学习笔记整理一下 xff0c 分享给自己的同学们 同时也做一个小Demo xff0c 让没有接触过MVC开发的同学 xff0c
  • ASP.NET - MVC框架及搭建教程

    一 MVC简介 MVC xff1a Model View Controller xff08 模型 视图 控制器 xff09 xff0c MVC是一种软件开发架构模式 1 模型 xff08 Model xff09 模型对象是实现应用程序数据域
  • Web 绘图—服务器端绘图

    Web服务器端绘图的基本原理是 xff1a 首先在内存中创建一个Bitmap位图 xff0c 然后在此位图上绘制任意想要的图形 xff0c 绘制完成后保存输出到页面的输出流 这样 xff0c 一个页面就转换成了绘制的图片 1 xff0e 简
  • 在VS2015中安装Qt环境

    1 安装Qt 1 xff09 下载 下载网址 xff1a https download qt io archive qt 选择要下载的版本 xff0c 我选择5 12 5 xff0c 点击下载即可 点击 Detail 按钮可以看到安装文件资
  • Qt Quick 中 QML 与 C++ 混合编程详解

    Qt Quick 技术的引入 xff0c 使得你能够快速构建 UI xff0c 具有动画 各种绚丽效果的 UI 都不在话下 但它不是万能的 xff0c 也有很多局限性 xff0c 原来 Qt 的一些技术 xff0c 比如低阶的网络编程如 Q
  • windows消息机制深入详解-1

    Windows 是一个事件驱动的操作系统 事件驱动围绕着消息的产生与处 理展开 xff0c 事件驱动是靠消息循环机制来实现的 也可以理解为消息是一种报告有关事件发生 的通知 xff0c 消息是Windows 操作系统的灵魂 在屏幕显示一个窗
  • windows消息机制详解-3

    1 引言 Windows 在操作系统平台占有绝对统治地位 xff0c 基于Windows 的编程和开发越来越广泛 Dos 是过程驱动的 xff0c 而Windows 是事件驱动的 6 xff0c 这种差别的存在使得很多Dos 程序员不能 习
  • vnc server安装教程,在win系统下如何进行vnc server安装

    在日常工作中 xff0c 经常会使用到vnc server xff0c 那有小伙伴知道vnc server是什么吗 xff1f vnc server 是一般 Linux 发行版都会附带的 vnc服务器软件 vncserver 是一个为了满足
  • Windows消息机制详解-2

    消息是指什么 xff1f 消息系统对于一个win32程序来说十分重要 xff0c 它是一个程序运行的动力源泉 一个消息 xff0c 是系统定义的一个32位的值 xff0c 他唯一的定义了一个事件 xff0c 向 Windows发出一个通知

随机推荐

  • windows消息机制-4(MFC)

    消息分类与消息队列 Windows中 xff0c 消息使用统一的结构体 xff08 MSG xff09 来存放信息 xff0c 其中message表明消息的具体的类型 xff0c 而wParam xff0c lParam是其最灵活的两个变量
  • Windows消息机制详解-5

    一 什么是消息 在解释什么是消息之前 xff0c 我们先讨论一下程序的执行机制问题 大体上说 xff0c 程序按照执行机制可以分为两类 xff1a 第一类是过程驱动 比如我们最早接触编程时写的C程序 xff0c 又或者单片机程序 这类程序往
  • Windows句柄-2

    这里需要说明 xff1a 1 这里将句柄所能标识的所有东西 xff08 如窗口 文件 画笔等 xff09 统称为 对象 2 图中一个小横框表示一定大小的内存区域 xff0c 并不代表一个字节 xff0c 如标有0X00000AC6的横框表示
  • Windows消息机制详解-6

    消息系统对于一个win32程序来说十分重要 xff0c 它是一个程序运行的动力源泉 一个消息 xff0c 是系统定义的一个32位的值 xff0c 他唯一的定义了一个事件 xff0c 向 Windows发出一个通知 xff0c 告诉应用程序某
  • TranslateMessage ,GetMessage, DispatchMessage分析

    TranslateMessage amp msg TranslateMessage是用来把快捷键消息转换为字符消息 并将转换后的新消息投递到调用线程的消息队列中 由于Windows对所有键盘编码都是采用虚拟键的定义 xff0c 这样当按键按
  • Windows消息机制-PreTranslateMessage

    PreTranslateMessage作用和使用方法 Windows消息机制的流程 xff1a A 操作系统接收应用程序的窗口消息 xff0c 将消息投递到该应用程序的消息队列中 B 应用程序在消息循环中调用GetMessage函数从消息队
  • 线程中发送消息阻塞问题解决

    发送消息时阻塞的两种方案1 此处应post发送消息放到消息队列中 xff0c 直接send调用响应过程的话如果消息响应未结束则会一直阻塞工作线程2 用send的话在此处开辟工作线程执行逻辑
  • qt+visa实现程控实例

    软件环境 系统 windows 10开发环境 Qt 5 80visa库版本 visa 6 0 软件下载 QtNI MAXIVI 步骤 1 添加依赖库 在Demo pro中添加依赖 win32 INCLUDEPATH 43 61 34 C P
  • Qt中标准对话框实例,QObject::tr()的作用

    函数 tr 全名是QObject tr 被它处理的 字符串可以 使用工具提 取出来翻译 成其他语言 也就是做国际化使用 只要记住 Qt 的最佳实践 如果你想让你的程序国际化的话 那么 所有用户可见的字符串都要使用 QObject tr 但是
  • 公司电脑安装了vncserver,公司电脑安装了vncserver怎么卸载vncserver

    在使用vncserver时感觉很方便 xff0c 但在卸载vncserver时往往比较让人头疼 xff0c 之前公司电脑安装了vncserver使用时我还比较庆幸 xff0c 但当我卸载时真的费了很多力气 xff0c 那今天小编就来教教大家
  • 进程,线程,消息循环的关系

    一个进程有n个线程 xff0c 一个线程有一个消息队列或事件队列和一个活动的消息循环 xff0c 每个模态窗体有一个消息循环函数和一个消息响应过程函数 xff0c 一个线程里哪个模态窗体激活即运行哪个窗体的消息循环 xff0c 一个模态窗体
  • Qt匿名函数的写法

    匿名函数也可以被叫做Lambda表达式 xff0c 自C 43 43 11中引入该特性 本文主要介绍Qt里使用到的匿名函数 c11新特性中加入了lambda表达式 xff0c 所以Qt 也支持 需在 pro文件中加入 CONFIG 43 6
  • QT c++ 中使用PostMessage/SendMessage实例

    PostMessage是Windows API 应用程序接口 中的一个常用函数 xff0c 用于将一条消息放入到消息队列中 并且不会等待响应的线程处理消息 xff0c 而是直接返回 xff08 简单的理解就是异步 xff09 而SendMe
  • Qt-线程启动与关闭实例

    养成资源回收的好习惯 xff0c 任何时候都要想起开辟过的内存回收 就是利用关闭窗口时调用槽函数回收掉 具体步骤不难 xff0c 如下 xff1a 1 xff09 退出线程 xff1b 2 xff09 回收子线程 xff1b 3 xff09
  • qt中QListView的用法和QModelIndex的使用

    使用QTreeView xff0c 对于很多函数中针对item的唯一标识QModelIndex的使用 xff0c 记录下两种对于QModelIdex的使用 1 xff0c 树形结构的item设置为选中 QModelIndex rootInd
  • Qt-QMessageBox用法详解

    QMessageBox 是 Qt 框架中常用的一个类 xff0c 可以生成各式各样 各种用途的消息对话框 xff0c 如图 1 所示 图 1 QMessageBox消息对话框 很多 GUI 程序都会用到消息对话框 xff0c 且很多场景中使
  • Qt-手动布局

    简述 手动布局 xff0c 可以实现和水平布局 垂直布局 网格布局等相同的效果 xff0c 也可实现属于自己的自定义布局 xff0c 当窗体缩放时 xff0c 控件可以随之变化 其对于坐标系的建立有严格要求 xff0c 纯代码思维 xff0
  • Qt-5种布局控件详解

    实际开发中 xff0c 一个界面上可能包含十几个控件 xff0c 手动调整它们的位置既费时又费力 作为一款成熟的 GUI 框架 xff0c Qt 提供了很多摆放控件的辅助工具 xff08 又称布局管理器或者布局控件 xff09 xff0c
  • vnc怎么设置自适应屏幕,2种方法教你vnc怎么设置自适应屏幕

    VNC 是在基于 UNIX和 LINUX 操作系统的免费的开源软件 xff0c 远程控制能力强大 xff0c 高效实用 xff0c 其性能可以和 WIndows和 MAC 中的任何远程控制软件媲美 在使用vnc软件的过程中 xff0c 往往
  • C++中的野指针问题

    文章目录 1 C和C 43 43 中的野指针问题 1 1 野指针的概念 1 2 野指针的由来 1 3 杜绝野指针的基本原则 2 C和C 43 43 中的常见内存错误 2 1 常见内存错误 2 2 内存操作的基本规则 1 C和C 43 43