指针的一些细节补充———C语言

news/2024/9/18 9:20:32/ 标签: c语言, 数据结构, 开发语言

 野指针:

 1.未初始化的指针

eg:
int *p;       // 未初始化的指针
*p = 5;       // 未定义行为,p 是野指针
———————————————————————————————————————————————————————————————————————————————————————————
//解决方法:
//在动态内存开辟完成后应该进行检查
int *p = (int *)malloc(sizeof(int));
if (p == NULL) {// 处理内存分配失败的情况return -1;
}
———————————————————————————————————————————————————————————————————————————————————————————
//进行及时的初始化
int value = 42;
int *p = &value;  // 在声明时初始化

2.指向已经释放的内存

//动态内存释放后继续使用指针:
#include <stdio.h>
#include <stdlib.h>int main() {int *p = (int *)malloc(sizeof(int));  // 动态分配内存*p = 42;                              // 使用内存free(p);                              // 释放内存*p = 24;  // 错误:悬空指针访问,未定义行为
//解决方法:
//应该将指针进行滞空free(p);p = NULL;printf("%d\n", *p);  // 未定义行为,输出可能随机return 0;
}
—————————————————————————————————————————————————————————————————————————————————————————
//进行重复的释放:
#include <stdlib.h>int main() {int *p = (int *)malloc(sizeof(int));free(p);   // 第一次释放free(p);   // 错误:重复释放,未定义行为
//解决方法:
//进行重复释放的判断
if (p != NULL) {free(p);p = NULL;
}return 0;
}
—————————————————————————————————————————————————————————————————————————————————————————
//指针副本仍指向已释放的内存
#include <stdio.h>
#include <stdlib.h>int main() {int *p1 = (int *)malloc(sizeof(int));  // 动态分配内存int *p2 = p1;                          // p2 也是悬空指针free(p1);  // 释放内存,p1和p2现在都指向已释放的内存// 任何对p2的访问都是未定义行为*p2 = 10;  // 未定义行为printf("%d\n", *p2);  // 未定义行为return 0;
}

3.指向超出变量生命周期的内存

//指向函数内局部变量的指针:
#include <stdio.h>int* getPointer() {int x = 10;  // 局部变量 x 的生命周期在函数结束时终止//在int前加static使用静态变量return &x;   // 返回局部变量的地址,危险操作,返回后就已经是悬空指针了
}int main() {int *p = getPointer();  // p 现在是一个悬空指针printf("%d\n", *p);     // 未定义行为,可能会打印垃圾值或导致程序崩溃return 0;
}
—————————————————————————————————————————————————————————————————————————————————————————
//指向作用域内局部变量的指针
#include <stdio.h>int* pointerOutsideScope() {int *p;{int y = 20;  // y 是代码块内的局部变量p = &y;      // p 指向 y 的内存地址}// 此时 y 的生命周期结束,p 是一个悬空指针return p;
//使用int *p = (int *)malloc(sizeof(int));*p = 10;  // 动态内存的生命周期由程序员控制return p;
}int main() {int *ptr = pointerOutsideScope();printf("%d\n", *ptr);  // 未定义行为,可能打印垃圾值return 0;
}

4.指向已经重新分配的内存

#include <stdio.h>
#include <stdlib.h>int main() {int *p = (int *)malloc(10 * sizeof(int));  // 分配内存if (p == NULL) {printf("Memory allocation failed\n");return -1;}// 初始化数组for (int i = 0; i < 10; i++) {p[i] = i + 1;  }int *q = p;  // q 和 p 指向同一块内存p = (int *)realloc(p, 20 * sizeof(int));  // 重新分配内存if (p == NULL) {printf("Memory reallocation failed\n");free(q);  // 如果 realloc 失败,释放原内存return -1;}// q 现在是悬空指针,因为内存可能已经被移动printf("%d\n", q[0]);  // 未定义行为,q 指向无效内存free(p);  // 释放新的内存块return 0;
}

指针运算:

1.指针+-整数

如何获取数组中最后一个元素的地址arr+size-1 或 &arr[size-1]

#define N_VALUES 5 // 定义数组的长度
#include <stdio.h>
int main() {
float values[N_VALUES] = { -1 };
float* vp;
for (vp = &values[0]; vp < &values[N_VALUES];) {
*vp++ = 0;
}
return 0;
}

2.指针-指针

会得到两个指针中间元素的个数

int main() {
int arr[5] = { 13,34,21,38,49 };
int res = &arr[4] - &arr[0];
printf("%d\n", res);
return 0;
}

75bbca418f8346eca9516f75d3b9e061.png

指针的关系运算

#define N_VALUES 5 // 定义数组的长度
#include <stdio.h>
int main() {float values[N_VALUES] = { -1 };float* vp;for (vp = &values[N_VALUES]; vp > &values[0];) {*vp++ = 0;}return 0;
}

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

指针函数:

本质是函数不过返回值是地址

#include <stdio.h>
float* designArray(int* p_length){static float arr[]={68.5,75.4,69.8,90,75.6,78};int size = sizeof(arr)/sizeof(arr[0]);*p_length = size;return arr;//返回的是一个地址
}
void showArr(float* arr,int length){for(int i=0;i<length;i++){printf("%-8.2f",*(arr+i));}printf("\n");
}
int main()
{int length = 0;float* result = designArray(&length);
//ouput arrshowArr(result,length);return 0;
}

函数指针:

指向函数的指针

#include <stdio.h>
int getMax(int a,int b){//对应的指针类型int (*)(int,int)return a>b?a:b;
}
int main()
{int a=0,b=0;printf("input two data:");scanf("%d%d",&a,&b);int max = getMax(a,b);printf("The maximum values of %d and %d are %d\n",a,b,max);
return 0;
}

回调函数

#include <stdio.h>
int add(int a,int b){
return a + b;
}
int sub(int a,int b){
return a - b;
}
int calc(int a,int b,int (*pfun)(int,int)){return pfun(a,b);
}
int main(){int a=0,b=0;printf("input two data:");scanf("%d%d",&a,&b);int result = calc(a,b,add);//在一个函数中调用另一个函数printf("a + b = %d\n",result);result = calc(a,b,sub);printf("a - b = %d\n",result);
return 0;
}

36302c9e504f436c9b27dfd6482546bf.png

  • 这是本人的学习笔记不是获利的工具,小作者会一直写下去,希望大家能多多监督我
  • 文章会每攒够两篇进行更新发布(受平台原因,也是希望能让更多的人看见)
  • 感谢各位的阅读希望我的文章会对诸君有所帮助

 


http://www.ppmy.cn/news/1518528.html

相关文章

R语言股价跳跃点识别:隐马尔可夫hmm和 GARCH-Jump对sp500金融时间序列分析

全文链接&#xff1a;https://tecdat.cn/?p37479 分析师&#xff1a;Yue Ji 在突发事件发生后&#xff0c;股价会相应的发生较大幅度的上涨或下跌&#xff0c;称为跳跃现象&#xff0c;跳跃现象会给金融投资带来极大风险&#xff0c;因而对跳跃点的识别对于风控而言是很重要的…

Github 2024-08-27 Python开源项目日报 Top10

根据Github Trendings的统计,今日(2024-08-27统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10C项目1Home Assistant | 本地控制和隐私优先的开源家庭自动化项目 创建周期:3773 天开发语言:Python协议类型:Apache License 2…

岩石检测检测系统源码分享 # [一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

岩石检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

MySQL——事务与存储过程(二)存储过程的创建(2) 变量的使用

在编写存储过程时&#xff0c;有时会需要使用变量保存数据处理过程中的值。在 MySQL中时&#xff0c;可以在子程序中声明并使用&#xff0c;这些变量的作用范围是在BEGIN...END程序中&#xff0c;接下将针对变量的定义和赋值进行详细的讲解。 想要在存储过程中使用变量&#xf…

【jvm】局部变量表

目录 1. 说明2. 容量与大小3. 存储机制4. 生命周期5. 槽位重用6. 与成员变量的对比 1. 说明 1.JVM&#xff08;Java虚拟机&#xff09;中的局部变量表&#xff08;Local Variables Table&#xff09;是JVM执行方法时的一个重要组成部分&#xff0c;用于存储方法中定义的局部变…

筑牢技术防线:服务器故障后的应急响应与未来防范策略

在数字化浪潮中&#xff0c;每一个技术节点都牵动着服务的稳定与用户的信任。网易云音乐作为业界知名的音乐平台&#xff0c;其服务器故障事件不仅是一次技术挑战&#xff0c;更是对团队应急响应能力与未来防范措施的一次深刻考验。本文将从快速响应、问题排查、高效解决及长期…

chrome extension sendmessage async

遇到的问题&#xff1a; Chrome 插件开发&#xff0c;需要实现 content 页面使用 chrome.runtime.sendMessage 发送消息给 background&#xff0c;background 需要异步处理完消息以后再发送处理结果给content 页面。 解决思路和方法&#xff1a; google 找到的解决方法&#x…

快速掌握GPTEngineer:用AI创建网页应用的实用教程

今天来聊聊一个非常有趣的工具——GPTEngineer。这是一个基于AI的网页开发平台&#xff0c;特别适合那些不熟悉编程但又想快速创建网页应用的人。如果你想用简单的文本描述来生成一个网站或者应用&#xff0c;GPTEngineer可能就是你需要的。我们一步步看看如何使用它。 1. 了解…

DSP48E2使用以及FIR滤波器定点设计实现与优化

DSP48E2使用以及FIR滤波器定点设计实现与优化 DSP48E2是数字信号处理中最常用的FPGA硬核资源&#xff0c;对于高效率&#xff0c;低消耗实现数字信号处理算法有着极为重要的意义。因此熟练掌握DSP48E2的使用是算法工程化的必备技能。FIR滤波器是因果系统&#xff0c;只有零点没…

Spring Boot 项目中,配合 Nacos 、Gateway使用 MinIO

在现代微服务架构中&#xff0c;将不同服务整合并高效地管理配置和流量是至关重要的。Spring Cloud Gateway、Nacos 和 MinIO 是三个关键组件&#xff0c;它们可以一起工作&#xff0c;提供一个灵活、动态和高效的解决方案。下面的方案展示了如何将这三个组件结合起来&#xff…

Nginx: https解决安全问题

https原理 1 &#xff09;http协议存在的问题 数据使用明文传输&#xff0c;可能被黑客窃取 (需要信息加密)报文的完整性无法验证&#xff0c;可能被黑客篡改 (需要完整性校验)无法验证通信双方的身份&#xff0c;可能被黑客伪装 (需要身份认证) 2 ) https 原理 所谓 https,…

【前端面试基础】计算机网络、浏览器、操作系统

计算机网络 一、网络协议与模型 什么是协议&#xff1f; 协议是指计算机系统中完成特定任务所必需的规则和约定&#xff0c;特别是数据传输和交换的规则和约定。OSI和TCP/IP是什么&#xff1f; OSI&#xff08;开放式系统互连参考模型&#xff09;是一种网络架构模型&#xf…

黑神话悟空-妖怪平生录PDF

通关黑神话悟空&#xff0c;并且解锁了两个结局。感触不是那么深&#xff0c;我个人的感觉是剧情上面不如国产单机古剑奇谭三。 与其说黑神话悟空是西游记的延续&#xff0c;不如说是游科CEO对斗战神的执念。 不过&#xff0c;这里面的游记是真的很惊艳&#xff0c;203个妖怪…

Openai api via azure error: NotFoundError: 404 Resource not found

题意&#xff1a;"OpenAI API通过Azure出错&#xff1a;NotFoundError: 404 找不到资源" 问题背景&#xff1a; thanks to the university account my team and I were able to get openai credits through microsoft azure. The problem is that now, trying to us…

Zookeeper官网Java示例代码解读(一)

2024-08-22 1. 基本信息 官网地址&#xff1a; https://zookeeper.apache.org/doc/r3.8.4/javaExample.html 示例设计思路 Conventionally, ZooKeeper applications are broken into two units, one which maintains the connection, and the other which monitors data. I…

c-数据结构(顺序表、链表)

概念 对于n各元素的线性表&#xff0c;严格数学定义&#xff1a;其中任意一个数据元素a[i]&#xff0c;有且仅有一个前驱a[i-1]&#xff0c;有且仅有一个后继a[i1]&#xff1b;首元素a[0]无前驱&#xff0c;尾元素a[n-1]无后继。 顺序表 属于线性表&#xff0c;数据之间的空…

在 Java 中使用泛型时遇到的问题,,无法正确将响应数据映射为需要的数据

public <T> List<T> getOrderList(String shopId, Class<T> tClass) {// --- 省略一些中间过程----ParameterizedTypeReference<KeRuYunCommonResultVO<KPOSPageResultVO<T>>> responseType new ParameterizedTypeReference<KeRuYunCom…

Python日志,按日期分割日志文件(每天一个新的日志文件)

为了创建一个Python类来管理日志&#xff0c;并使其支持按日期分割日志文件&#xff08;每天一个新的日志文件&#xff09;&#xff0c;你可以使用Python标准库中的logging模块和logging.handlers.TimedRotatingFileHandler。下面是一个简单的示例&#xff0c;展示了如何实现这…

linux怎么安装Android Studio

方法一 下载安装包到linux系统解压 tar.gz文件的解压方式为 tar -zxvf 文件名&#xff08;tar -zxvf filename.tar.gz 命令的作用是&#xff0c;使用gzip解压缩&#xff08;-z&#xff09;&#xff0c;解包&#xff08;-x&#xff09;名为filename.tar.gz的归档文件&#xf…

使用PostgreSQL的CLI客户端查询数据不显示问题

问题 今天在使用PostgreSQL的命令行工具&#xff08;CLI&#xff09;查询数据时&#xff0c;数据不显示问题。 解决 使用CLI客户端登录数据库后&#xff0c;需要设置打印&#xff0c;设置边框为2: peterlocalhost testdb> \pset border 2或者&#xff0c;使用元组方式显…