浅谈c/c++面试中的指针数组越界-野指针空指针-指针数组数组指针问题

指针的定义

  指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。简单的说,电脑内存中的每一个字节都有一个编号,指针中存储的就是这个编号,可以找到唯一确定的一个内存单元。我们通常写代码中定义的*p,这个并不是真正意义上的指针,而是指针变量。

易混淆的问题

  1. 指针减去一个指针,得到结果并不是字节差,而是中间差了多少个相同的类型,也就是字节差还要除以指针的类型。
  2. 指针大小和指针加i的理解,指针在32位计算机下是4个字节,在64位下可以是4字节,也可以是8字节,具体看情况,指针是存地址的,一个字节能表示的最大范围是0~255,而这对于计算机来说是远远不够的,因此,需要4个字节,一个字节是2 ^8,4个字节是2 ^32,而对于指针加i来说,指针表示的是这组数据中的第一个元素的首地址,当i等于1时,数据加对应类型的地址。

实例

在这里插入图片描述
代码

#include <stdio.h>
int main()
{
	int i = 0;
	int arr[10] = { 0 };
	int* a = arr;
	for (i = 0; i <= 12; i++)
	{
		*(a+i) = 0;
		printf("sb %d", i);
	}

	return 0;
}

  简单的分析一下代码,创建一个int类型的数组,数组可以存10个数据,字节大小为40,因为初始化第一个元素为0,后面未初始化,所以后面的元素默认为0,然后创建了一个int类型的指针,里面存储的是数组arr下的第一个元素的地址,for循环循环13次,很明显这已经超出数组的范围,,并且循环中将数组内的元素又重新赋值为0,并且打印出sb和i的值,细心的人还会发现,函数明明循环12次,但是在打印过程中并没有输出过12。之后,通过运行会发现,这段代码首先没有报错,并且是一个死循环,这是因为系统对于数组的越界是进行抽查的,并不是所有的越界编译器都能发现,对于死循环这个问题,我通过调试查看arr首元素的地址,进行调试
在这里插入图片描述
  地址0x00D5FC68为arr首元素的地址,地址0x00D5FC98为i的地址,由于数组越界,将i的值在第12循环时重新赋值为0,导致循环在重新开始,反复如此形成死循环。

野指针

  官方说就是未初始化的指针和数组越界的指针,通俗的讲就是不知道指针指向了哪里。编译器在使用的时候往往可以取到里面的值,但是在程序结束释放资源的时候,因为这部分资源原本就不属于它,因此程序就会出现问题。

空指针

  不指向任何对象或者函数的指针,在初始化、赋值或者比较的时候,如果一边是指针类型的值或表达式,编译器可以确定另一边的常数0为空指针并生成正确的空指针值。

char *p = 0;
if (p != 0)

野指针和空指针辨析

  野指针是指向任意位置的指针,空指针确保不指向任何对象或者函数。两者的声明方式和来源也不同,合理的利用空指针可以避免内存泄露。

指针数组和数组指针辨析

  指针数组和数组指针两者截然不同,指针数组本质上任然是数组,只是数组中存储的数据都是指针类型,而数组指针本质上是指针,是一个指向数组的指针。其中两者的定义方法也是不同的。

//指针数组
int* arr1[10];
//数组指针
int  arr2[10];
int (*p2)[10] = &arr2;

  这两种方法定义出来的初始值是一样的,但是当给两个同时加1时, 指针数组改变了1个字节,数组指针却需要改变4个字节。

猜你喜欢

转载自blog.csdn.net/weixin_43580319/article/details/111196008