C语言常见标准库函数

string.h

memset

stdlib.h

malloc

malloc 是 C 语言中的一个标准库函数,用于动态分配内存。其全称为 “memory allocation”,可以根据程序的需要在运行时分配指定大小的内存块。

1
void* malloc(size_t size);

参数说明:

size:要分配的内存块的大小,以字节为单位。

返回值:

malloc 返回一个指向新分配的内存块的指针,如果分配失败,则返回 NULL。

功能和用途

  1. 动态内存分配:malloc 可以在运行时分配指定大小的内存块,并返回指向该内存块的指针。
  2. 内存分配器:malloc 是内存分配器,它负责管理内存,分配和释放内存。
  3. 堆内存:malloc 分配的内存块在堆上,由 malloc 和 free 进行管理。

示例:

  1. 动态分配一个 10 字节的内存块:
1
2
int *ptr = (int *)malloc(sizeof(int) * 10);
memset(ptr, 0, sizeof(int) * 10); // 初始化为 0
  1. 动态分配一个 100 字节的内存块:
1
2
char *str = (char *)malloc(sizeof(char) * 100);
memset(str, 0, sizeof(char) * 100); // 初始化为 0

注意事项:

  1. 内存分配器:malloc 是内存分配器,它负责管理内存,分配和释放内存。malloc 并不直接分配内存,而是返回指向新分配的内存块的指针。
  2. 堆内存:malloc 分配的内存块在堆上,由 malloc 和 free 进行管理。
  3. 内存分配失败:如果 malloc 不能分配足够的内存,则返回 NULL。
  4. 内存对齐:malloc 并不保证分配的内存块的地址是 8 字节对齐的,也不保证分配的内存块的大小是 8 字节的倍数。
  5. 内存泄漏:如果分配的内存块不再需要,则应该使用 free 释放它,以避免内存泄漏。

总结:malloc 是 C 语言中的一个重要的标准库函数,用于动态分配内存,并返回指向该内存块的指针。它可以分配任意大小的内存块,并管理堆内存,避免内存泄漏。

calloc

calloc 是 C 语言中的一个标准库函数,用于动态分配内存,主要用于分配一个数组并初始化为零。其全称为 “contiguous allocation”。

1
void* calloc(size_t num, size_t size);

参数说明:
num:要分配的内存块的数量。
size:每个内存块的大小,以字节为单位。

返回值:
calloc 返回一个指向新分配的内存块的指针,如果分配失败,则返回 NULL。

功能和用途

  1. 动态内存分配:calloc 可以在运行时分配指定数量和大小的内存块,并返回指向该内存块的指针。
  2. 内存分配器:calloc 是内存分配器,它负责管理内存,分配和释放内存。
  3. 堆内存:calloc 分配的内存块在堆上,由 calloc 和 free 进行管理。
  4. 内存初始化:calloc 会将分配的内存块初始化为零。

示例:

1
2
int *ptr = (int *)calloc(10, sizeof(int));
// ptr 现在指向一个包含 10 个 int 值的数组,且所有元素都被初始化为 0

注意事项:

  1. 内存分配器:calloc 是内存分配器,它负责管理内存,分配和释放内存。calloc 并不直接分配内存,而是返回指向新分配的内存块的指针。
  2. 堆内存:calloc 分配的内存块在堆上,由 calloc 和 free 进行管理。
  3. 内存分配失败:如果 calloc 不能分配足够的内存,则返回 NULL。
  4. 内存对齐:calloc 并不保证分配的内存块的地址是 8 字节对齐的,也不保证分配的内存块的大小是 8 字节的倍数。
  5. 内存泄漏:如果分配的内存块不再需要,则应该使用 free 释放它,以避免内存泄漏。

总结:calloc 是 C 语言中的一个重要的标准库函数,用于动态分配内存,并返回指向该内存块的指针。它可以分配指定数量和大小的内存块,并初始化为零,管理堆内存,避免内存泄漏。

free

free 是 C 语言中的一个标准库函数,定义在 stdlib.h 头文件中。它的主要作用是释放之前通过动态内存分配(例如使用 malloc、calloc 或 realloc 函数)所分配的内存。

1
void free(void *ptr);

参数说明:

ptr:指向要释放的内存块的指针,该指针必须是先前通过动态内存分配函数获得的。如果指针为 NULL,则 free 不会做任何事情。

功能和用途

  1. 释放内存:当不再需要动态分配的内存时,使用 free 可以释放该内存,以免造成内存泄漏。
  2. 重用内存:释放内存后,该内存区域可以被后续的动态内存分配请求重新使用。

注意事项

避免非法释放:只应释放之前通过动态内存分配获得的指针,不能重复释放同一个指针(即两次调用 free 释放同一个指针),也不能释放栈上或静态分配的内存。

置空指针:在调用 free 之后,通常建议将指针置为 NULL,以防止悬挂指针(dangling pointer)的产生。

1
2
3
4
5
6
7
8
int *ptr = (int *)malloc(sizeof(int) * 10); // 动态分配内存
if (ptr != NULL) {
// 使用 ptr
}

// 释放内存
free(ptr);
ptr = NULL; // 避免悬挂指针

总之,free 是管理动态内存的重要函数,用于释放不再需要的内存,以避免内存泄漏和提高程序的内存使用效率。

stdio.h

sprintf

sprintf 的全称是 “string print formatted”,意为“格式化字符串输出”。它用于将格式化的数据输出到一个字符串中,函数名称的 “s” 表示字符串(string),”print” 则表示打印或输出,”formatted” 则表示输出的数据是按照特定格式的。

sprintf 是 C 语言中的一个标准库函数,定义在 stdio.h 头文件中。它的主要功能是将格式化的数据写入字符串中。

1
int sprintf(char *str, const char *format, ...);

参数说明:

  1. str:指向一个字符数组的指针,sprintf 将在这个数组中存储格式化后的字符串。
  2. format:一个格式字符串,类似于 printf 的格式化字符串,用于指定如何格式化后续参数。
  3. …:后续的参数,这些参数将根据格式字符串进行格式化。

返回值:

  1. sprintf 返回写入 str 中的字符数,不包括终止的空字符(\0)。
  2. 如果发生错误,返回值是一个负数。

示例:

1
2
3
4
char buffer[100];
int number = 42;
sprintf(buffer, "The answer is %d", number);
// buffer 现在包含 "The answer is 42"

注意事项:

  1. 缓冲区溢出:使用 sprintf 可能导致缓冲区溢出,因为如果生成的字符串长度超过 str 提供的容量,可能会覆盖其他内存区域。
  2. 为了避免这种情况,推荐使用 snprintf,可以指定要写入的字符数,提供更加安全的方式。

总之,sprintf 是一个强大的字符串格式化函数,但在使用时需要特别注意缓冲区的大小,以避免潜在的安全隐患。

snprintf

snprintf 的名称实际上并没有官方的全称,其命名是由其功能所暗示的。

“s” 表示字符串(string)。
“n” 表示限制(limit or number),指的是可以指定最大写入字符数。
“printf” 则表示打印格式化输出。

所以,虽然并没有一个正式的全称,但可以理解为 “formatted print to string with size limit”。

snprintf 是 C 语言中的一个标准库函数,定义在 stdio.h 头文件中。它的功能与 sprintf 类似,主要用于将格式化的数据写入字符串,但 snprintf 具有更好的安全性,因为它可以限制写入的字符数。

1
int snprintf(char *str, size_t size, const char *format, ...);

参数说明:
str:指向一个字符数组的指针,用于存储格式化后的字符串。
size:要写入的最大字符数,包括终止的空字符(\0)。这为防止缓冲区溢出提供了保护。
format:格式字符串,指定如何格式化后续参数,类似于 printf 的格式化字符串。
…:后续的参数,这些参数将根据格式字符串进行格式化。

返回值:
snprintf 返回写入 str 中的字符数(不包括终止的空字符),如果生成的字符串的长度超过 size,则返回需要的字符数(这可以用于调整缓冲区大小)。
如果发生错误,返回值是一个负数。

示例:

1
2
3
4
5
6
7
8
char buffer[50];
int number = 42;

// 格式化数据并写入 buffer,最多写入 50 个字符
int len = snprintf(buffer, sizeof(buffer), "The answer is %d", number);

// buffer 现在包含 "The answer is 42"
// len 为实际写入的字符数

优势:
安全性:相较于 sprintf,snprintf 的最大字符数参数可以有效防止缓冲区溢出,提高了安全性。
灵活性:通过返回值可以判断所需的缓冲区大小,有助于动态内存分配。
总结:
snprintf 是一个更安全的格式化字符串输出函数,推荐在处理字符串格式化时使用,尤其是在不确定最终字符串长度的情况下。