精华内容
下载资源
问答
  • 取消对NUll指针的引用

    2020-02-19 19:58:03
    如题,而且运行过后它一直在输入也不输出 ``` #include #include struct student { ...取消对 NULL 指针“pend”的引用。查看第 14 行以找出可能会发生此情况的前一位置 取消对 NULL 指针“pnew”的引用
  • 导图引用what is 引用?翔曰:“引用者,绰号也。” 哈哈哈,话粗理不粗,...众所周知,c++从某一方面来说是c的威力加强版,因此在设计之初,c++委员会既想保留c指针的高效性,又想避开指针操作不慎带来的bug,于...

    2a7254e1a28d0d981a7fbfb327d9bfa2.png

    导图

    408251e93e961a8b11e0aca598b95fb4.png

    引用

    • what is 引用?
      翔曰:“引用者,绰号也。” 哈哈哈,话粗理不粗,人(变量)只有一个,但是绰号可以很多。官方解释引用是变量的别名,不是实体类型【注释1】。它长这样子:
      int a = 94;
      int &b = a;//引用必须初始化
    • 引用从何而来?
      众所周知,c++从某一方面来说是c的威力加强版,因此在设计之初,c++委员会既想保留c指针的高效性,又想避开对指针操作不慎带来的bug,于是引入了引用 这一概念想要取代指针操作,却发现指针太牛掰了,根本取代不了,引用也有了其他的用途(伟大的发现总是不经意间诞生的是吧,比如“某哥”)。
    • 引用在哪使用?
      • 从函数中返回引用时,一定要保证在函数返回以后,被引用的目标一直有效,也就是不能返回局部变量的引用,因为一旦函数返回,局部变量都会被析构。
        int& func(int a);
      • 使用引用作为形参,那么形参和实参就是同一个对象,也就不存在对象的复制,避免了复制的开销(划重点!);
      • 修改形参也就相当于修改实参。
      • 实际利用的比较多的是优势是避免开销。
        int func(int &a);
    1. 引用型形参 :
    2. 引用型 返回值 :
    • 注意
    • 引用必须初始化(作为形参时,但传入实参时初始化);
    • 引用不能更换目标,比如:
      int a = 94;
      int c = 95;
      int &b = a;
      b = c;//错误,引用不能更改目标

    指针

    • what is 指针?
      翔曰:“指针者,一曰实体,二曰数据类型。” 指针作为实体时,是用来保存一个内存地址的变量 ;作为数据类型时,指针类型描述了一种对象,其值为对被引用类型实体的引用。没错,这是百度百科上说的官解,看完我也一脸懵逼,怎么理解呢?其实就是:
      int a = 94;
      int* pa = &a;//"&"在这里是取地址符,不是引用
      对于上述代码,pa就是实体,int*就是数据类型。对于一个指针实体而言,我们主要考察“指针类型(也就是数据类型)”、“指针所指向的类型”、“指针的值”、“指针本身所占的内存区大小”。
    • 指针的值
      指针的值是指指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值,比如:
      int* pa = (int*)1;
      这里pa的值就是1(一般写作0x1,因为是地址),当编译器解析pa时,不会直接取出1就直接用,而是拿着它去找索引为1的那一块内存【注释2】,取出这块内存中的值来使用。
    • 指针所指向的类型
      例如:
      int a = 94;
      int* pa = &a;
      这里pa指向的类型就是int。(也就是说,从右往左,指针所指的类型就是消去一个"*"后所剩的部分。
    • 指针本身所占据的内存区大小
      在任何机器上(64bit or 32bit)使用sizeof()即可查看指针的大小:
      int a = 94;
      double b = 94.0;
      complex c;
      int* pa = &a;
      double* pb = &b;
      complex* pc = &c;
      //下述输出均在32bit机器上
      cout << sizeof(pa) << endl;//输出 4
      cout << sizeof(pb) << endl;//输出 4
      cout << sizeof(pc) << endl;//输出 4
      由上可知,不论指针指向的类型是啥,指针本身的大小都是4字节。也就是说指针的大小与指向的类型无关。那为什么会是4字节呢?思考一下【注释3】。
    • 其他
      理解了指针上面这四个地方,其他的都是弟弟哈哈哈哈、

    指针与引用的区别

    • 存在空指针,不存在空引用;
      void* p = NULL;//空指针,合法
      void& r = NULL;//空引用,不合法
    • 指针可以不初始化(有的编译器会警告),引用不可以不初始化;
    • 存在指针数组,但不存在引用数组。
      int* parr[3] = {&x, &y, &z};//指针数组,合法
      int& rarr[3] = {x, y, z};//引用数组,不合法

    总结

    • 在c++底层中,引用是通过指针实现的,也就是说,在实现层面,引用就是指针,但在语言层面,引用不是实体类型;
    • 我们通常所说的指针是实体;
    • 指针就类似于你对象的门牌号,知道了门牌号才能去提亲是吧~;
    • 微信后台发送131获取注释内容;
    • 最后喜欢我的文章请点赞关注加收藏,谢谢~。

    5c2febf85bd0ae7764670f1a575510e4.png
    展开全文
  • 在使用之前,定义了很多结构体,当然这些结构体都不重要,只是让为了完成知识点而定义结构体。 初始化分配动态内存 ...这是对对指针分配了动态内存空间 使用已经分配动态内存的指针后 会发现这样

    在使用之前,定义了很多结构体,当然这些结构体都不重要,只是让为了完成知识点而定义的结构体。
    在这里插入图片描述

    初始化分配动态内存

    void Init(AdjListGraph& G){
    	G.adjlist = new AdjList[MaxSize];
    	G.edge = 0;
    	G.vex = 0;
    
    	for (int i = 0; i < MaxSize; i++) {
    		visited[i] = false;
    	}
    }
    

    这是对对指针分配了动态内存空间

    使用已经分配动态内存的指针后
    在这里插入图片描述
    在这里插入图片描述
    会发现这样的问题:取消对NULL指针的引用。
    而我们上面已经为它分配了动态内存空间,却还是出现了这样的原因,是为什么呢?

    解决方法
    在这里插入图片描述
    就是在使用这个指针的时候,先做一个防御性编程,来对这个指针判断是否分配动态内存成功,如果失败,则结束程序(根据不同的返回类型来定义)。
    会发现添加了这个防御性编程之后,警告也就不见了。

    在这里插入图片描述
    希望能够帮助到大家!!!

    展开全文
  • 在前面用Malloc申请了一块内存,然后后面就提示取消对NULL指针的引用,中间判断过了,指针不是NULL啊?并且其他的变量也会提示没有初始化!程序串行执行没有问题,但是用mpiexec并行执行时就会报错![img=...
  • 因此,指针的大小不会像其他变量一样变化,只跟当前平台相关——不同平台内存地址的范围是不一样的,32位平台下,内存最大为4GB,因此只需要32bit就可以存下,所以sizeof(pointer)的大小是4字节。64位平台下,32位...

    1、指针和引用的本质(是什么)

    (1)指针是存放内存地址的一种变量,特殊的地方就在它存放的是内存地址。因此,指针的大小不会像其他变量一样变化,只跟当前平台相关——不同平台内存地址的范围是不一样的,32位平台下,内存最大为4GB,因此只需要32bit就可以存下,所以sizeof(pointer)的大小是4字节。64位平台下,32位就不够用了,要想内存地址能够都一一表示,就需要64bit(但是目前应该没有这么大的内存吧?),因此sizeof(pointer)是8。

    (2)引用的本质是“变量的别名”,就是给变量又重新起了一个名字,既然是“别名”,那么就一定要有本体。

    2、声明和初始化时的区别

    指针指向的是一个内存地址, 因此可以指向一块为0x00000000的地址,声明时可以暂时不初始化(不推荐),即pointer = NULL;

    引用是变量的别名,别名就一定对应着一个“本名”,因此必须在声明时就初始化,且不能初始化为空。

    3、使用时区别

    (1)根据声明和初始化时二者的区别,指针在声明周期内随时可能会为Null,所以使用时一定要做检查,防止出现空指针、野指针的情况;而引用则不用再操这个心,只要初始化了,在哪里都可以直接使用,再也不用担心它会不会为空什么的了。

    (2)指针因为自己存的是一个内存地址,既然可以存初始化(或者赋值)的地址,那么在指针生命周期内就可以存其他的地址,只要你是同一类型(不同类型这个对应的类型偏移不一样)的变量,对于指针都OK。

    引用作为一个变量AA的别名,在它的整个生命周期内,它只能“从一而终”,始终是第一次初始化它的那个变量的别名,在这期间任何对它的操作,都等同于对变量AA的操作。

    Now,talk is cheap,show you my code.

        /** 指针和引用的例子 **/
    
        std::string s1 = "萝卜";
        std::string s2 = "青菜";
        std::string s3 = "鸡蛋";
        std::string s4 = "西红柿";
        /** 指针可以初始化为空 **/
        std::string *p_Str = NULL;
        /** 引用一开始必须初始化 **/
        std::string& r_Str = s1;
    
        p_Str = &s2;
        std::cout<<"我是指针"<<*p_Str<<std::endl; /** 青菜 **/
        std::cout<<"我是引用"<<r_Str<<std::endl;  /** 萝卜 **/
        std::cout<<std::endl;
        std::cout<<"*********分别修改指针和引用***********"<<std::endl;
        /** 分别修改指针和引用 **/
        r_Str = s3;  /** 试图让r_Str为s3的别名 **/
        p_Str = &s4; /** p_Str重新指向了s4 **/
        
        std::cout<<"我是指针"<<*p_Str<<std::endl;  /** 西红柿 **/
        std::cout<<"我是引用"<<r_Str<<std::endl;   /** 鸡蛋 **/
        std::cout<<std::endl;
        std::cout<<"*********查看刚刚的修改对最初初始化的影响***********"<<std::endl;
        /** 貌似成功了,都按照意图修改了,但是,稍等 **/
        std::cout<<"我是s1"<<s1<<std::endl;  /** 鸡蛋 !!!注意 !!!  **/
        std::cout<<"我是s2"<<s2<<std::endl;  /** 青菜 **/
        std::cout<<"我是s3"<<s3<<std::endl;  /** 鸡蛋 **/
        std::cout<<"我是s4"<<s4<<std::endl;  /** 西红柿 **/
    
        /** 
        发现s1 "萝卜"  被变成了和s3一样的"青菜",这也说明了任何对引用的操作都等同于操作原先的变量本身
        相比较之下,指针就自由度很高了,想指向谁就指向谁,并不会影响任何之前指向过的变量
        惊不惊喜,意不意外 :)
        **/

    4、总结

    一个不大恰当的比喻是,指针就像是一个可以(注意是可以,但未必一定)到处沾花惹草(可以随时指向任意地址)的“渣男”;而引用则像是一个只能“从一(谁初始化就跟谁)而终”的“老实人”。

    另外,根据Scott Meyers在《More Effective C++》上所讲,只有当你确定需要一开始就初始化,并且不需要再指向其他类型时 使用引用,否则你都应该使用指针。

    小弟认识粗鄙浅薄,有不当之处,请大佬轻拍。

    展开全文
  • 当变量声明为引用时,它将成为现有变量替代名称。通过在声明中添加“&”,可以将变量声明为引用。#include using namespace std; int main() { int x = 10; // ref is a reference to x. int& ref = x; // ...
    725e27655b4a4d3e9aeef6260bd2bd1c.png

    当变量声明为引用时,它将成为现有变量的替代名称。通过在声明中添加“&”,可以将变量声明为引用。

    #include using namespace std;   int main() {   int x = 10;     // ref is a reference to x.   int& ref = x;     // Value of x is now changed to 20   ref = 20;   cout << "x = " << x << endl ;     // Value of x is now changed to 30   x = 30;   cout << "ref = " << ref << endl ;     return 0; } 

    输出:

    x = 20ref = 30

    应用

    1. 修改函数中传递的参数:如果函数收到对变量的引用,则可以修改变量的值。 例如,在以下程序变量中使用引用进行交换。

    #include using namespace std;   void swap (int& first, int& second) {     int temp = first;     first = second;     second = temp; }   int main() {     int a = 2, b = 3;     swap( a, b );     cout << a << " " << b;     return 0; } 

    输出:

    3 2 

    2. 避免复制大型结构:想象一个函数必须接收一个大型对象。如果我们不加引用地传递它,就会创建一个新的副本,这会导致CPU时间和内存的浪费。我们可以使用引用来避免这种情况。

    struct Student {    string name;    string address;    int rollNo; }   // If we remove & in below function, a new // copy of the student object is created.  // We use const to avoid accidental updates // in the function as the purpose of the function // is to print s only. void print(const Student &s) {     cout << s.name << "  " << s.address << "  " << s.rollNo; } 

    3. 在For Each循环中修改所有对象:我们可以使用For Each循环中的引用修改所有元素。

    #include   using namespace std;    int main()  {      vector vect{ 10, 20, 30, 40 };        // We can modify elements if we      // use reference     for (int &x : vect)          x = x + 5;       // Printing elements     for (int x : vect)         cout << x << " ";        return 0;  }  

    4. 在For-Each循环中避免对象的复制:我们可以在For-Each循环中使用引用,以避免在对象较大时复制单个对象。

    #include   using namespace std;    int main()  {      vector vect{"geeksforgeeks practice",                       "geeksforgeeks write",                      "geeksforgeeks ide"};        // We avoid copy of the whole string     // object by using reference.     for (const auto &x : vect)         cout << x << endl;        return 0;  } 

    引用与指针

    引用和指针都可以用来更改一个函数在另一个函数中的局部变量。当作为参数传递给函数或从函数返回时,它们都还可以用于保存大对象的副本,以提高效率。

    尽管有上述相似之处,但引用和指针之间仍存在以下差异。

    可以将指针声明为void,但引用永远不能为void。

    例如:

    int a = 10;void* aa = &a;. //it is validvoid &ar = a; // it is not valid

    引用没有指针强大

    1)一旦创建了引用,以后就不能使它引用另一个对象;不能重新放置它。这通常是用指针完成的。

    2)引用不能为NULL。指针通常被设置为NULL,以指示它们没有指向任何有效的对象。

    3)引用必须在声明时进行初始化。指针没有这种限制。

    由于上述限制,C++中的引用不能用于实现链接列表,树等数据结构。在Java中,引用没有上述限制,可以用于实现所有数据结构。引用在Java中更强大,这是Java不需要指针的主要原因。

    引用更安全,更易于使用

    1)更安全:由于必须初始化引用,因此不太可能存在诸如野指针之类的野引用。

    2)易于使用:引用不需要解引用运算符即可访问值。它们可以像普通变量一样使用。仅在声明时才需要“&”运算符。另外,对象引用的成员可以使用点运算符('.')访问,这与需要使用箭头运算符(->)访问成员的指针不同。

    结合上述原因,在像复制构造函数参数这样的地方不能使用指针,必须使用引用传递副本构造函数中的参数。类似地,必须使用引用来重载某些运算符,例如++。

    展开全文
  • 今天在调试程序过程中,用到了一些指针的方法,这里记录一下野指针的概念。1.概念野指针,也就是指向不可用内存区域的指针。通常这种指针进行操作的话,将会使程序发生不可预知的错误。 野指针与空指针(NULL)不同...
  • 初学C++时,很容易把指针引用的用法混在一起,下面通过一些示例来说明指针引用两者之间差别。1、两者定义和性质不同指针是一个变量,存储是一个地址,指向内存一个存储单元;引用是原变量一个别名,跟...
  • 这段时间比较忙,我就简单阐述一点点自己对于指针的初始化以及多重指针的想法。如果说的有什么不对的地方,欢迎指出!“野指针”这个概念,可能很多和我一样的初学者都有耳闻。我们往往只是知道不能让自己的程序出现...
  • 二、基本类型与引用类型2.1 基本类型2.2 引用类型Java有三种引用类型,类、接口、数组,默认值均为null,其中,枚举是特殊的类,String是特殊的引用类型。(此处注意:对于Java,主流观点是三种引用类型,类(包括枚举...
  • int Locate(LinkNode* L, ElemType key)//查找结点值等于key结点 { LinkNode* p; int i = 1; p = L->next; while (p != 0) { if (p->data != key) p = p->next; else ...
  • 函数参数是一个一级指针,可以传递内存吗?如果函数参数是一个一级指针,不要指望用该指针去申请动态内存。...//指针引用操作才是更新其指向// 这里没有解引用,直接操作指针本身,而不...
  • 一、概述在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用。在这四个引用类型中,只有强...(我是C语言入门编程,指针的概念还是很深入我心。)通过引用,可以堆中的对象进行操作。如:StringBuffer ...
  • ES.65: Don't dereference an invalid pointerES.65:不要解引用无效指针Reason(原因)Dereferencing an invalid pointer, such as nullptr, is undefined behavior, typically leading to immediate crashes, wrong ...
  • 来源:公众号【编程珠玑】作者:守望先生ID:...》中介绍过NULL和0区别,本文决定再补充一些内容,做一些说明。NULL与数字0是不是等价?在C语言中,NULL一般有如下定义(在stddef.h中):1#defineNULL((void...
  • 强类型语言中所有变量都有自己固定类型,这个类型有固定内存占用,有固定 解析方法;而弱类型语言中没有类型概念,所有变量全都是一个类型(一般都是字符串),程序在用时候再根据需要来处理变量。(2)...
  • 第八章 指针§8.1 指针概述【 概念】指针:是数据类型一种, 其内容存储是另外一个变量地址。注意:地址:设备操作系统中物理内存中存储单元编号,编号由操作系统自动分配,无需人为干预。【指针数据类型...
  • 指针是一种数据类型指针变量指针是一种数据类型,占用内存空间,用来保存内存地址。void test01(){ int* p1 = 0x1234; int*** p2 = 0x1111; printf("p1 size:%d\n",sizeof(p1)); printf("p2 size:%d\n",sizeof(p2));...
  • idl语法和C语言非常类似,但是它扩展了一些特性,这些特性用于兼容其它语言特性,或者是用来表示RPC中行为。我们先从idl中简单地数据类型说起,然后再将它一些属性。一、枚举类型和C语言类似,我们可以用enum...
  • 警告 C6011 取消对NULL指针XXX的引用

    万次阅读 2019-11-06 20:28:35
    若要更正此警告,请检查指针是否有 null 值 #include <malloc.h> void f( ) { char *p = ( char * )malloc ( 10 ); if ( p ) { *p = '\0';...官方解释:警告 C6011:取消引用 NULL 指针 &l...
  • NULL指针取消引用应该早在几年前就已终止...介绍我们在本文中讨论漏洞NULL指针取消引用位于win32k.sys驱动程序中,该驱动程序导致Windows 7和Windows Server 2008操作系统上特权(EoP)成功升级。Microsoft在7月补...
  • 取消对NULL指针“…”的引用

    千次阅读 2020-04-15 23:01:32
    警告c6011 取消对NULL指针“…”的引用一般是由于分配内存时没有添加判断语句或者循环条件不足。如: 判断while循环的条件不足,应该将逻辑或(||)改为逻辑与(&&)。 ...
  • 什么叫做指针的取值?指针是一个存储计算机内存地址的变量。在这份教程里“引用”表示计算机内存地址。从指针指向的内存读取数据称作指针的取值。指针可以指向某些具体类型的变量地址,例如 int、long 和 double。...
  • 用动态内存分配函数malloc分配内存时,经常会出现“取消对NULL指针的‘、、、’的引用”的警告,这是因为在写代码时,没有加判动态分配的内存是否分配成功的语句造成的。下面以用malloc函数存储10个整数为例,进行...
  • 、间接寻址运算符 * #include结果如下:Value of var :0x61fe14Value of p :1二、引用引用是C++中特有概念,非常容易与指针混淆在一起。先明确引用的定义: int *p;//指针 int m; //被引用变量 p = &m; int...
  • (给CPP开发者加星标,...有时候,一个空指针解引用,或者访问到野指针等,都会造成程序的崩溃。本文主要介绍C++智能指针的详细用法,不熟悉的朋友可以一起来学习学习。c++ 智能指针用法详解本文介绍c++里面的四...
  • 1 引言举个例子: 在func函数退出后,指针pInt所指内容*pInt为 12#include//公众号:C语言与CPP编程intfunc(int*pRes){if(pRes==NULL)pRes=newint(12);//分配新内存空间给指针pRes,并赋值return0;}intmain(){int...
  • 今天在调试程序过程中,用到了一些指针的方法,这里记录一下野指针的概念。1.概念野指针,也就是指向不可用内存区域的指针。通常这种指针进行操作的话,将会使程序发生不可预知的错误。 野指针与空指针(NULL)不同...

空空如也

空空如也

1 2 3 4
收藏数 75
精华内容 30
关键字:

取消对null指针的引用