当前位置: 首页 > news >正文

函数指针与指针函数练习讲解

练习1:
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
{
puts("Gota null pointer");
}
else
{
puts("Gota valid pointer");
}
请问指针为NULL时指向哪里,分配的空间为0时又指向哪里?

完整代码:

#include <stdio.h>
#include <stdlib.h>int main() {char* ptr;// 尝试分配0字节内存ptr = (char*)malloc(0);if (ptr == NULL) {puts("Gota null pointer");}else {puts("Gota valid pointer");// 虽然指针有效,但解引用是未定义行为// *ptr = 'A';  // 错误:不要解引用// 可以安全释放free(ptr);}return 0;
}

代码解析:

这段代码主要是调用malloc(0)来尝试分配 0 字节的内存,然后依据返回值来判断分配是否成功。具体逻辑为:

  • 若返回的是NULL,就表明分配失败,此时会输出Gota null pointer
  • 若返回的是一个有效的指针,那就意味着分配成功,会输出Gota valid pointer

练习2:会出现什么问题?
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,"hello world");
}

int main()
{
char *str=NULL;
getmemory(str);
printf("%s\n",str);
free(str);
return 0;
}
错误分析:

  1. 内存泄漏
    getmemory 分配的内存地址存储在局部变量 p 中,函数返回后该地址丢失,导致内存无法释放。

  2. 未定义行为
    printf("%s\n", str) 尝试打印 NULL 指针,以及 free(str) 释放 NULL 指针(虽然释放 NULL 是安全的,但此处逻辑错误)。

解决办法:

  1. 正确传递指针

    • 使用二级指针 char **p 并传递 &str,或直接返回指针。
  2. 内存分配检查

    • 始终检查 malloc 的返回值是否为 NULL,避免后续操作空指针。

修改后的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void getmemory(char **p) {*p = (char *)malloc(100);if (*p == NULL) {exit(EXIT_FAILURE);}// snprintf(目标地址, 最大长度, 格式化字符串, 参数...)snprintf(*p, 100, "hello world");  // 自动截断超长内容
}int main() {char *str = NULL;getmemory(&str);printf("%s\n", str);free(str);return 0;
}

运行结果:

练习3:会出现什么问题?
void GetMemory( char *p )
{
p = (char *) malloc( 100 );
}

int main() 
{
char *str = NULL;
GetMemory( str ); 
strcpy( str, "hello world" );
printf( str );
}
错误原因:

  1. 指针传递方式错误(内存泄漏)
    GetMemory 函数通过值传递接收指针 p,这意味着函数内部对 p 的修改(如分配内存)不会影响外部的 str 指针。因此,main 中的 str 仍然是 NULL,而 malloc 分配的内存地址被丢弃,导致内存泄漏。

  2. 空指针解引用(未定义行为)strcpy(str, "hello world") 尝试向 NULL 指针写入数据,这会触发段错误(Segmentation Fault),程序崩溃。

修复:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void GetMemory(char** p) {*p = (char*)malloc(100);if (*p == NULL) {exit(EXIT_FAILURE);}
}int main() {char* str = NULL;GetMemory(&str);// 只需改这一行!用 snprintf 替代 strcpysnprintf(str, 100, "hello world");printf("%s\n", str);free(str);return 0;
}


文章转载自:
http://abb.alwpc.cn
http://artificialize.alwpc.cn
http://abampere.alwpc.cn
http://callous.alwpc.cn
http://antifebrin.alwpc.cn
http://appraisingly.alwpc.cn
http://algol.alwpc.cn
http://awag.alwpc.cn
http://bucktooth.alwpc.cn
http://acquirable.alwpc.cn
http://azorean.alwpc.cn
http://beltane.alwpc.cn
http://betrothal.alwpc.cn
http://afterpains.alwpc.cn
http://anemosis.alwpc.cn
http://bractlet.alwpc.cn
http://blewits.alwpc.cn
http://absoluteness.alwpc.cn
http://assentient.alwpc.cn
http://behead.alwpc.cn
http://aponeurosis.alwpc.cn
http://amusive.alwpc.cn
http://chiliasm.alwpc.cn
http://barreled.alwpc.cn
http://bluebell.alwpc.cn
http://afreet.alwpc.cn
http://autocorrelator.alwpc.cn
http://autecological.alwpc.cn
http://bewray.alwpc.cn
http://beryl.alwpc.cn
http://www.dtcms.com/a/281746.html

相关文章:

  • 9、线程理论1
  • HostVDS 云服务器测评:平价入门、流媒体解锁全美、表现稳定
  • 暑假Python基础整理 --异常处理及程序调试
  • Redis 中的持久化机制:RDB 与 AOF
  • Java之Stream其二
  • 第二章 OB 存储引擎高级技术
  • 数学金融与金融工程:学科差异与选择指南
  • 【AI News | 20250714】每日AI进展
  • 为 Git branch 命令添加描述功能
  • 将 Vue 3 + Vite + TS 项目打包为 .exe 文件
  • 711SJBH构建制造业信息化人才培训体系的对策-开题报告
  • 21-C#的委托简单使用-1
  • Datawhale 25年7月组队学习coze-ai-assistant Task1学习笔记:动手实践第一个AI Agent—英伦生活口语陪练精灵
  • yolov5、yolov8、yolov11、yolov12如何训练及轻量化部署-netron-onnx
  • echarts折线图的 线条的样式怎么控制
  • Python os模块完全指南:从入门到实战
  • python编程实现GUI界面的排序与查找算法动态模拟演示程序
  • Sa-Token使用要点
  • mongoDB安装初始化及简单介绍
  • 2025/7/15——java学习总结
  • Pandas 和 NumPy 使用文档整理
  • 大宗现货电子盘交易系统核心功能代码解析
  • QT6 源,六章事件系统(8)QEvent 的孙子类:QEnterEvent 光标进入
  • 无穿戴动捕如何凭借摄像头视觉识别算法,赋能高校专业教学革新?
  • python进阶
  • 145-变分模态分解VMD与平稳小波变换SWT信号降噪算法实现!
  • 4G模块 A7680通过MQTT协议连接到onenet(新版)
  • WebAPIs基本认知,DOM基础介绍
  • 基于Springboot+UniApp+Ai实现模拟面试小工具五:权限校验参数校验及日志功能实现
  • Ubuntu 22.04 安装 mysql-server与 postgreSQL 服务端