内存分配与文件读写

#define

C语言变为exe的过程中需要经过替换,编译,链接三个阶段

define所做的工作就是在编译阶段之前完成替换,他可以实现一些函数的功能,函数在执行的时候需要分配堆栈,但是define不需要,更加节省空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "stdafx.h"
#include <stdlib.h>
#include "windows.h"

#define TRUE1 1
#define PI1 3.1415926
#define MAX(A,B) ((A)>(B)?(A):(B))

void fun()
{
printf("%d\n",TRUE1);
}

void fun1()
{
printf("%f\n",PI1);
}

int fun2(int x,int y)
{
return MAX(x,y);
}

int main(int argc, char* argv[])
{
fun();
fun1();
int a=fun2(2,3);
printf("%d\n",a);

getchar();
return 0;

}

image-20240115143239222

头文件

1
2
3
4
5
6
7
C语言的头文件(Header File)是一些包含常量、变量、函数声明、结构体、共用体等代码的文件,可以被其他文件包含(即通过预处理器指令 #include 引入)以便在源代码中使用其中定义的内容。头文件通常以 .h 作为后缀名。


头文件的主要作用是为了让程序的实现更加模块化与可维护。通常将常用的函数和变量声明放在头文件中,然后在其他源文件中引用这些头文件,从而减少程序的重复代码量,使得程序的实现更加清晰、简洁和易于维护。头文件还提高了程序的可重用性,因为相同的头文件可以供多个不同的程序使用。


C语言标准库中提供了很多预定义的头文件,如 stdio.h、stdlib.h、string.h 等,它们包含了一些常用的函数和变量声明,如输入输出操作、内存管理、字符串操作等。此外,编程人员还可以定义自己的头文件以供自己的程序使用。

重复包含问题,当A文件与B文件都包含C文件的时候正常运行没有问题,但是当我们创建一个新文件D,这个D文件包含A和B文件,由于A和B都包含了C,这时候C会被重复引用出现问题

内存分配与释放

int等声明变量就是在申请内存,但是这是大小固定的申请内存空间,我们需要一个根据实际需求动态申请内存空间的方法

使用动态申请的内存都在堆里,用完需要告诉操作系统已经使用结束,也就是需要释放这块内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// TEST.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>

int main(int argc, char* argv[])
{
int* ptr;
//分配空间
ptr =(int*)malloc(sizeof(int)*128);

//判断空间是否正确申请
if(ptr==null)
{
return 0;
}

//初始化空间
memset(ptr,0,sizeof(int)*128);

//释放空间
free(ptr);

//把指针置为0
ptr=null;

return 0;
}

文件读写

将记事本的notepad.exe文件读取到内存,并返回读取后在内存中的地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// TEST.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

void* read_file_to_memory(const char* filename,size_t* out_size)
{
//定义一个函数,将文件读入内存并返回内存地址
FILE* file=fopen(filename,"rb");
if(!file)
{
return NULL;
}

//测量文件大小
fseek(file,0,SEEK_END);
size_t size=(size_t)ftell(file);

//重新定义文件指针到开头
rewind(file);

//申请内存,读取文件内容
void* buffer=malloc(size);
if(!buffer)
{
return NULL;
}
size_t read_size = fread(buffer, 1, size, file);
if (read_size != size) {
fclose(file);
free(buffer);
return NULL;
}

//关闭文件
fclose(file);
return buffer;
}

int main(int argc, char* argv[])
{
char* filename = "C:\\Windows\\system32\\notepad.exe";
size_t size;
void* address = read_file_to_memory(filename, &size);
if (address) {
printf("File %s loaded at address %p.\n", filename, address);
free(address);
}
getchar();
return 0;
}

将内存中的数据以.exe的格式存储到一个文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// TEST.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

void fun()
{
// 打开要读取的文件
FILE* from_file = fopen("C:\\Windows\\system32\\notepad.exe", "rb");
if (!from_file) {
printf("Failed to open input file.\n");
exit(1);
}

// 获取文件大小
fseek(from_file, 0, SEEK_END); // 将文件位置指针移到文件末尾
long file_size = ftell(from_file); // 获取文件大小
fclose(from_file); // 关闭文件

// 打开要写入的文件
FILE* to_file = fopen("C:\\Windows\\system32\\notepad_copy.exe", "wb");
if (!to_file) {
printf("Failed to open output file.\n");
exit(1);
}

// 分配足够大的缓冲区
void *buffer = malloc(file_size);

// 读取数据到缓冲区中
from_file = fopen("C:\\Windows\\system32\\notepad.exe", "rb");
if (!from_file) {
printf("Failed to open input file.\n");
exit(1);
}
fread(buffer, file_size, 1, from_file);
fclose(from_file);

// 将缓冲区中的数据写入到文件中
fwrite(buffer, file_size, 1, to_file);

// 释放缓冲区
free(buffer);

// 关闭文件
fclose(to_file);

printf("File copied successfully.\n");

}

int main(int argc, char* argv[])
{
fun();
getchar();
return 0;
}

image-20240115143422989