C语言之指针的含义,指针类型的定义及使用方法,野指针的定义,以及原因,如何避免野指针

简介: C语言之指针的含义,指针类型的定义及使用方法,野指针的定义,以及原因,如何避免野指针

指针的含义及使用方法

指针类型及使用方法

野指针的定义

野指针的成因及如何避免野指针

指针的定义:本质上是一个变量,用来存储地址的变量,因此,可以以形象的把地址称为指针,指针称为地址。

举例

​ int a = 10;//在内存中开辟一块空间
  int* p = &a;    //对变量a,使用操作符&取它的地址
        //将a的地址存放在变量p中,p是指针变量,用来存放地址的

小tips:一个单元的大小是一个字节,在32位平台上,一个指针变量(地址)的大小是4个字节,在64位平台上,一个指针变量(地址)的大小是8个字节。

指针和指针类型

1:指针的大小:32位平台上指针的大小位4个字节,64位平台上指针的大小为8个字节。

代码如下所示:

  printf("%d\n", sizeof(int*));
  printf("%d\n", sizeof(char*));
  printf("%d\n", sizeof(float*));
  printf("%d\n", sizeof(double*));
  printf("%d\n", sizeof(short*));

输出结果如下所示:

4
  4
  4
  4

代码如下所示:

  int a = 0x11223344;
  int* pa = &a;
  char* pc = &a;
  printf("%p\n", pa);
  printf("%p\n", pc);

输出结果如下所示:

通过上述所举的例子我们可以看出指针变量类型的不同并没有影响地址的存放,那么指针变量的类型是不是没有意义呢?答案肯定不是的,下面我们继续研究指针变量类型。

当指针变量和变量本身是同一种类型时:

  int a = 0x11223344;
  int* pc = &a;
  printf("%p\n", *pc);
  *pc = 0;
  printf("%p\n", *pc);


输出结果如下所示

当指针变量和变量本身不是同一种类型时:

  int a = 0x11223344;
  char* pc = &a;
  printf("%p\n", *pc);
  *pc = 0;
  printf("%p\n", *pc);

输出结果如下所示:


通过对比上面两种情况,我们可以得出的结论是:**指针类型决定了指针进行解引用操作的时候,能够访问空间的大小,int*p: *p能够访问4个字节 char *p: *p能够访问1个字节 double p: p能够访问8个字节。


此外,指针的类型还决定了指针的步长(字节);int *p:p+1–>4 char *p:p+1–>1 double

*p:p+1–>8


举例:

  int a = 0x11223344;
  int* pa = &a;
  char* pc = &a;
  printf("%p\n", pa);
  printf("%p\n", pa + 1);
  printf("%p\n", pc);
  printf("%p\n", pc+1);

输出如下:

那么这两个意义到底有什么作用呢?

举例说明:

  int arr[10] = { 0 };
  int* p = arr;
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    *(p + i) = 1;
    printf("%d\n", arr[i]);
  }

输出结果如下所示:

当我们把指针变量的类型替换为char类型再来看代码运行情况。

  int arr[10] = { 0 };
  char* p = arr;
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    *(p + i) = 1;
    printf("%d\n", arr[i]);
  }

输出结果如下所示:

因此在编译的时候我们可以通过实际情况去确定所需的指针变量类型。

野指针:

就是指指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)


野指针成因:

1:指针未进行初始化

举例:

  int* p;//局部变量不初始化,默认是随机值
  int a;//局部的指针变量,就被初始化随机值
  *p = 20;

2:指针越界访问:

举例:

  int arr[10] = { 0 };
  int* p = arr;
  int i = 0;
  for (i = 0; i <= 11; i++)
  {
    *(p++) = i;//随着p++的不断运行,当i越出了0-9这个范围,该指针就会变成野指针
  }

3:指针指向的空间释放:

举例:

int main()
{
  int* test();
  int* p = test();//此时调用test函数把a的地址赋给指针变量p
  *p = 20;//该代码是想将p里面存放的a值改为20
​     //但是由于a的内存已经被释放,a变量现在的地址已经发生改变,无法实现改变变量的值
​ return 0;
}
int *test()
{
  int a = 10;//a是一个局部变量,每次执行完该程序a的内存都会被释放,归还给系统
  return &a;//每次返回的地址都是系统随机给的
}

那么如何避免野指针呢?

1:指针初始化

2:小心指针越界

3:指针指向空间释放即使置NULL

4:指针只用之前检查有效性

相关文章
|
29天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
48 0
|
12天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
36 4
|
28天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
17 2
|
28天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
28天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
1月前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
1月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
1月前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
1月前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
1月前
|
C语言
C语言指针(3)
C语言指针(3)
14 1