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:指针只用之前检查有效性

相关文章
|
16天前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
86 14
|
20天前
|
C语言
【C语言】全局搜索变量却找不到定义?原来是因为宏!
使用条件编译和 `extern` 来管理全局变量的定义和声明是一种有效的技术,但应谨慎使用。在可能的情况下,应该优先考虑使用局部变量、函数参数和返回值、静态变量或者更高级的封装技术(如结构体和类)来减少全局变量的使用。
31 5
|
20天前
|
编译器 C语言
【C语言】宏定义在 a.c 中定义,如何在 b.c 中使用?
通过将宏定义放在头文件 `macros.h` 中,并在多个源文件中包含该头文件,我们能够在多个文件中共享宏定义。这种方法不仅提高了代码的重用性和一致性,还简化了维护和管理工作。本文通过具体示例展示了如何定义和使用宏定义,帮助读者更好地理解和应用宏定义的机制。
38 2
|
1月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
104 13
|
24天前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
68 4
|
24天前
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
40 2
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
88 4
|
2月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
2月前
|
存储 编译器 C语言
C语言:数组名作为类型、作为地址、对数组名取地址的区别
在C语言中,数组名可以作为类型、地址和取地址使用。数组名本身代表数组的首地址,作为地址时可以直接使用;作为类型时,用于声明指针或函数参数;取地址时,使用取地址符 (&),得到的是整个数组的地址,类型为指向该类型的指针。
|
2月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
44 2