day 24 vargrind 、linux系统编程

一、Valgrind 简介

Valgrind 是一款用于内存调试、内存泄漏检测和性能分析的开源工具集。它主要用于 Linux 系统,能够检测常见的内存错误(如非法访问、未初始化内存使用)和内存泄漏问题。

常用参数:

  • --leak-check=full:显示内存泄漏的详细堆栈信息。
  • --show-leak-kinds=all:显示所有类型的内存泄漏(确定、可能、间接)。
  • --track-origins=yes:追踪未初始化变量的来源。
  • --log-file=filename:将输出重定向到文件。

二、linux系统编程

Linux系统编程涉及直接调用Linux内核提供的系统调用和库函数,以控制硬件资源、管理进程、文件操作等。核心内容包括文件编程、多任务编程、网络编程。

如果要使用到linux系统的功能需要通过系统调用来使用到,系统调用--就是指linux系统本身提供的函数。

linux系统下,实现一个用户的应用程序两条路径:

1.直接通过系统调用直接实现

2.通过库的方式实现库--函数库--一般是别人基于linux系统调用实现的功能更丰富使用更方便的函数

(一)文件编程

1.基于库的方式实现

stdio --- standard input output//标准的输入输出函数

2.基于系统调用的方式实现

linux系统本身提供的函数

标准I0:

在linux系统下一切皆文件

文件 --- 一组相关信息的集合linux将很多东西都抽象成文件

"-"普通文件(常规文件)eg:1.txt 图片_视频音频可执行文件

"d"目录文件(directory) eg:文件夹目录 (ls -l 目录)

"c"字符设备文件(char) eg:某一个硬件鼠标,键盘,摄像头 ls -l /dev/input

"b"块设备文件(block) eg:硬盘等存储设备----512Bytes (ls -l /dev/sda)

"l"软连接文件(link) eg:相当于windows下快捷方式 (ls -l /usr/lib)//浅蓝色

"s"套接字文件(socket) eg:网络的时候会接触到主要指的是本地sockett ---进程间通信

"p"管道文件(pipe) eg:进程间通信 mkfifo pipe (ls -l pipe)

标准IO:

1.打开

fopen//file open---打开文件

2.读写

fgetc/fputc---//按字符读写

fgets/fputs---//按字符串读写

fread/fwrite---//按对象读写(二进制流读写)

3.关闭

fclose//file close

流:是对数据读写过程的抽象。

①fopen 流打开函数

#include <stdio.h>

FILE * fopen(const char *pathname, const char *mode)

功能:打开文件并关联一个流。

参数:@pathname要打开的文件的名字---字符串形式

@mode打开文件的模式

r:打开文件做读操作。(要求:文件必须存在,不存在会报错)

r+:打开文件做读写(要求:文件必须存在,不存在会报错)

w: 打开文件做只写(说明:如果文件存在,则被截断为0如果文件不存在,则创建)

w+:打开文件做读写(说明:如果文件存在,则被截断为0如果文件不存在,则创建)

a:打开文件做追加(只写)(文件存在,则定位到末尾开始写如果文件不存在,则创建)

a+:以追加方式打开文件(读写).(文件存在,写入位置定位到文件末尾;文件不存在,创建)

返回值:成功 FILE*;

FILE *--文件指针代表打开的文件流指针代表打开的文件(关联一个流);

失败NULL&errno(错误码-全局变量)

cs 复制代码
#include <stdio.h>
//命令行参数./a.out 1.txt
int main(int argc,const char *argv[])
{
	if(argc != 2)
	{
		printf("Usage:%s <filename>\n",argv[0]);
		return -1;
	}
	FILE *ph = fopen(argv[1],"r");
	if(ph == NULL)
	{
		perror("fail");
		return -1;
	}
	printf("success!\n");
	return 0;
}

②fgetc 读函数

int fgetc(FILE*stream);

功能:从流中获得数据(一次只能读取一个字符)

参数:@stream fopen成功打开文件后获得的流指针。

返回值:成功返回读取到的字符;

失败返回EOF(-1),当到达文件结尾也会返回EOF。

操作系统默认已经打开了三个流:

stdin---标准输入//FILE*指针//strucr_IO_FILE(键盘上ctrl + d可以产生一个EOF)

cs 复制代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
	int ret = 0;
	while((ret = fgetc(stdin)) != EOF)
	{
		printf("ret = %d:%c\n",ret,ret);
	}
	return 0;
}

stdout---标准输出

stderr---标准出错//也是个输出

③关闭文件

功能:关闭文件并断开关联的流

参数:@stream要关闭的流指针

返回值:成功0;失败EOF&&errno被设置

注意:同一个文件,只需要关闭一次

④ fputc 写函数

int fputc(int c,FILE*stream)

功能:将字符c输出到stream对应流中

参数:@c要输出的字符

@stream要输出到的流

返回值:成功输出了的字符;失败EOF。

cs 复制代码
	int ret = 0;
	while((ret = fgetc(ph)) != EOF)
	{
		//printf("%c",ret);
		fputc(ret,stdout);
	}
	fclose(ph);

⑤fgets //获取数据

char *fgets(char *s,int size,FILE*stream)

功能:从stream中读取数据:存放到s指定的空间最多读取size-1个字符

参数:@s---存放数据的空间

@size---表示要读取的字节数

@stream---表示要读取的文件流指针

返回值:成功:s ;失败:NULL。(到达文件结尾返回的也是NULL)

读取结束的条件:

1.到了EOF

2.读到了'\n';但是'\n'会被保存到s指定的空间

3.读满size-1;'\0'读取结束后,在s指定的空间中最后个字符后面加入'\0'

cs 复制代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
	char s[100] = {1,1,1,1,1,1,1,1,1,1};
	fgets(s,10,stdin);
	for(int i = 0;i < 10;i++)
	{
		printf("s[%d] = %c:%d\n",i,s[i],s[i]);
	}
	printf("s= %s\n",s);
	return 0;
}

练习:

cs 复制代码
#cat代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
	if(argc != 2)
	{
		printf("%sfile<filename>\n",argv[0]);
		return -1;
	}

	FILE *ph = fopen(argv[1],"r");
	if(ph == NULL)
	{
		perror("fail");
		return -1;
	}
	int c;
	while((c = fgetc(ph)) != EOF)
	{
		//printf("%c",ret);
		fputc(c,stdout);
	}
	fclose(ph);
	return 0;
}
cs 复制代码
#复制代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
	if(argc != 3)
	{
		printf("%sfile<filename>\n",argv[0]);
		return -1;
	}

	FILE *ph = fopen(argv[1],"r");
	FILE *fp = fopen(argv[2],"w");
	if(ph == NULL)
	{
		perror("fail");
		return -1;
	}
	int c;
	while((c = fgetc(ph)) != EOF)
	{
		//printf("%c",ret);
		fputc(c,fp);
	}
	fclose(ph);
	fclose(fp);
	return 0;
}
相关推荐
梦想很大很大17 小时前
拒绝“盲猜式”调优:在 Go Gin 项目中落地 OpenTelemetry 链路追踪
运维·后端·go
Sinclair18 小时前
内网服务器离线安装 Nginx+PHP+MySQL 的方法
运维
叶落阁主18 小时前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
0xDevNull1 天前
Linux切换JDK版本详细教程
linux
进击的丸子1 天前
虹软人脸服务器版SDK(Linux/ARM Pro)多线程调用及性能优化
linux·数据库·后端
茶杯梦轩1 天前
从零起步学习RabbitMQ || 第二章:RabbitMQ 深入理解概念 Producer、Consumer、Exchange、Queue 与企业实战案例
服务器·后端·消息队列
甲鱼9292 天前
MySQL 实战手记:日志管理与主从复制搭建全指南
运维
Johny_Zhao3 天前
OpenClaw安装部署教程
linux·人工智能·ai·云计算·系统运维·openclaw
YuMiao3 天前
gstatic连接问题导致Google Gemini / Studio页面乱码或图标缺失问题
服务器·网络协议
chlk1234 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统