malloc函数

分配一段内存空间,不会进行初始化

原型

void* malloc (size_t size);

头文件

#include<malloc.h>

返回值

分配成功则返回指向被分配内存的空类型指针,否则返回NULL。需要进行判断再决定下一步操作。
另外,需要进行强制转换。

字节计算

注意给字符串分配空间时,要多分配一位(因为要包含’\0’)。
计算好分配的空间,免得数据损坏其他内存中的数据引起错误

calloc函数

分配一段内存空间,并全部初始化为0

原型

void *calloc(size_t nitems, size_t size)
calloc()函数接受两个参数,都应是无符号整数。第一个参数是所需内存单元的数量,第二个参数是每个单元以字节计的大小。

头文件

<stdlib.h>

返回值

同malloc函数。

realloc函数

更改已经配置的内存空间,如更改由malloc()函数分配的内存空间的大小。

原型

void *realloc(void *ptr, size_t size)

参数说明

ptr:指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。
size :内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。

返回值

同malloc函数。

free函数

注意,在上述函数开辟的内存空间使用完毕后都要使用free函数,以避免内存泄漏。
free函数只能对同一地址进行一次,否则会报错。
注意由于free之后,指针变量仍指向原来的地址(成为野指针),为避免访问野指针,需要将指针变量初始化(一般置为NULL)。

关于sizeof()的运用

在分配内存的函数中,可以保证函数的可移植性。例如使用sizeof(int)而不是4,因为在不同机器上这一数值不一定都是4。

拓展

堆区/栈区

参考
这里不展开了。

rand()函数

伪随机函数。

原型

int rand(void)

头文件

返回值

返回一个范围在 0 到 RAND_MAX 之间的整数值。

使用方法

  1. int num = rand() % n +a;其中的a是起始值,n-1+a是终止值,n是整数的范围。
  2. 若要产生0~1之间的小数,则可以先取得0~10的整数,然后均除以10即可得到“随机到十分位”的10个随机小数。若要得到“随机到百分位”的随机小数,则需要先得到0~100的10个整数,然后均除以100,其它情况依 此类推。
  3. rand()产生的随机数在每次运行的时候都是与上一次相同的,这样是为了便于程序的调试。

为了产生真随机数,可以使用随机种子。
方法:srand(随机数种子)
如包含time.h头文件,然后使用srand(time(0))来使用当前时间使随机数发生器随机化,这样就可以保证每两次运行时可以得到不同的随机数序列,同时这要求程序的两次运行的间隔超过1秒。

system(“pause”);

用以使程序暂停,否则会一闪而过。
打印”Press any key to continue”。vc6.0编程会自动加上。

段错误

段错误

结构体

指针成员初始化问题

内存泄漏

一段内存空间失去了索引导致无法使用。注意这种情况只发生在堆内存中,栈内存会自动分配与释放。
如:忘记使用free()函数,导致程序终止之后指针变量被销毁,而所指向内存空间没有被释放。

注意:
当释放结构化的元素,而该元素又包含指向动态分配的内存位置的指针时,也可能会引起内存泄漏。
动态内存分配函数 - 图1
如图,若只释放p,会造成np所指内存的泄漏。正确方法是遍历p中所有元素,一 一进行释放。

内存溢出

指的是可用内存被消耗殆尽的现象。

与内存泄漏的关系

内存泄漏是造成内存溢出的原因之一(当然,内存泄漏并不一定会引起内存溢出)。

栈溢出和堆溢出

调试

542.01矩阵

栈(stack)

用于存储程序的局部数据。由编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈。一般情况下,应该避免使用指向栈内存的指针。

堆(heap)

一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收。
栈/堆溢出:
复制到缓冲区的数据大于缓冲区大小。
与野指针的关系问题:
指针内容

原因总结

  1. 当试图向堆或栈中超出数组范围的地址写入值时,必然会发生堆/栈溢出。
  2. 递归函数过多/变量过多/申请的数组长度过大,导致栈溢出。
  3. 动态分配的内存空间没有释放,逐渐积累导致堆溢出。(力扣解题时一般不会出现这个错误)

思考(542题):
为什么returnSize未被赋值时会出现heap buffer overflow?
542.01矩阵
非常简单。因为
returnSize用以系统读取matrix(位于堆内存中),当它没有赋值时,会读取到超出范围的地址。[

](https://www.yuque.com/daiguogongjiang/mo4k0v/qgc892#YAery)

缓冲区(buffer)

用来缓冲输入或输出的数据的存储空间。