news 2026/7/28 12:57:42

C/C\+\+ 内存与字符串操作函数详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C/C\+\+ 内存与字符串操作函数详解

C/C++ 内存与字符串操作函数详解

一、C 语言标准库函数(<string.h>/ C++ 中<cstring>

所有函数均为字节级裸指针操作,字符串默认以'\0'作为结束标志。

1. 内存操作函数(mem- 前缀 = memory 内存)

这类函数不关心内存中的数据类型,按字节数操作连续内存块。

  • memcpy(memory copy,内存拷贝)
    原型:void *memcpy(void *dest, const void *src, size_t n);
    从 src 地址拷贝 n 个字节到 dest 地址。不处理内存重叠,若源和目标区域重叠,行为未定义,重叠场景必须使用 memmove。

  • memmove(memory move,内存移动)
    原型:void *memmove(void *dest, const void *src, size_t n);
    功能同 memcpy,但支持内存区域重叠,内部通过临时缓存保证拷贝正确性,是实现字符串中间删除的核心函数。

  • memset(memory set,内存填充)
    原型:void *memset(void *s, int c, size_t n);
    将 s 指向的前 n 个字节全部赋值为字符 c。常用于内存清零、字符串清空,仅对 char 类型赋值任意值安全,不可用于给 int、结构体等非字节类型赋值非 0 值。

  • memcmp(memory compare,内存比较)
    原型:int memcmp(const void *s1, const void *s2, size_t n);
    按字节逐位比较前 n 个字节,返回值小于 0 表示 s1 更小,等于 0 表示完全相同,大于 0 表示 s1 更大。

  • memchr(memory character,内存字符查找)
    原型:void *memchr(const void *s, int c, size_t n);
    在前 n 个字节中查找字符 c 第一次出现的地址,找到返回对应指针,未找到返回 NULL。

2. 字符串操作函数(str- 前缀 = string 字符串)

所有字符串函数都依赖结尾的'\0'判断边界,操作前必须保证字符串合法结束。

(1)拷贝与赋值
  • strcpy(string copy,字符串拷贝)
    原型:char *strcpy(char *dest, const char *src);
    将 src 完整拷贝到 dest,包含结尾的'\0'。不检查 dest 容量,存在缓冲区溢出风险。

  • strncpy(string n copy,受限长度字符串拷贝)
    原型:char *strncpy(char *dest, const char *src, size_t n);
    最多拷贝 n 个字符。注意:若 src 长度 ≥ n,拷贝后不会自动追加'\0',需手动补全;若 src 更短,剩余位置自动用'\0'填充。

  • strdup(string duplicate,字符串复制)
    原型:char *strdup(const char *s);
    内部调用 malloc 分配堆内存并拷贝字符串,返回新字符串的首地址。使用后必须手动 free 释放,否则会造成内存泄漏。

(2)拼接追加
  • strcat(string concatenate,字符串拼接)
    原型:char *strcat(char *dest, const char *src);
    将 src 拼接到 dest 尾部,覆盖原结尾的'\0'并保留新的结束符。同样存在缓冲区溢出风险。

  • strncat(string n concatenate,受限长度字符串拼接)
    原型:char *strncat(char *dest, const char *src, size_t n);
    最多拼接 n 个字符,且会自动在末尾追加'\0',比 strcat 更安全。

(3)字符串比较
  • strcmp(string compare,字符串比较)
    原型:int strcmp(const char *s1, const char *s2);
    按 ASCII 字典序逐字符比较,返回值正负零分别表示 s1 小于、等于、大于 s2。

  • strncmp(string n compare,受限长度字符串比较)
    原型:int strncmp(const char *s1, const char *s2, size_t n);
    仅比较前 n 个字符,超出长度的部分不参与比较。

(4)查找与定位
  • strchr(string character,正向字符查找)
    原型:char *strchr(const char *s, int c);
    正向查找字符 c 在字符串中第一次出现的地址,未找到返回 NULL。

  • strrchr(string reverse character,反向字符查找)
    原型:char *strrchr(const char *s, int c);
    反向查找字符 c 最后一次出现的地址,r 代表 reverse(反向)。

  • strstr(string string,子串查找)
    原型:char *strstr(const char *haystack, const char *needle);
    在主串 haystack 中查找子串 needle 第一次出现的起始地址,未找到返回 NULL。

  • strspn(string span,前缀匹配长度)
    原型:size_t strspn(const char *s, const char *accept);
    返回字符串 s 开头连续包含 accept 字符集的字符个数,span 表示 “跨度、范围”。

  • strcspn(string complement span,前缀不匹配长度)
    原型:size_t strcspn(const char *s, const char *reject);
    返回字符串 s 开头连续不包含 reject 字符集的字符个数,c 代表 complement(补集)。

(5)长度与分割
  • strlen(string length,字符串长度)
    原型:size_t strlen(const char *s);
    返回字符串的字符个数,不包含结尾的'\0'

  • strtok(string token,字符串分割)
    原型:char *strtok(char *str, const char *delim);
    按分隔符 delim 分割字符串,首次调用传原串,后续传 NULL 继续分割。会修改原字符串,且不可重入、线程不安全;可重入版本为strtok_r(string token reentrant,可重入字符串分割),安全版本为strtok_s(string token safe,安全字符串分割)

(6)清空与删除(核心补充)

C 标准库没有提供名为 strdelete 的专属删除函数,字符串删除、清空均通过已有内存 / 字符串函数间接实现:

  1. 整串清空

    • strcpy(dest, ""):写入空字符串,仅修改首字节为'\0',效率最高。

    • memset(dest, 0, len):将整片内存清零,适合需要彻底清空数据的场景。

  2. 删除指定位置的字符 / 子串
    核心使用memmove实现:将删除位置后方的字符整体前移,覆盖被删除的内容,自动保留结尾的'\0'
    示例:删除字符串 s 中第 pos 位开始的 len 个字符

    memmove(s+pos,s+pos+len,strlen(s+pos+len)+1);

    必须使用 memmove 而非 memcpy,因为前移时源和目标内存区域重叠。


二、C++ 内存与字符串操作

C++ 完全兼容 C 语言的所有库函数,同时提供了面向对象的字符串类和更安全的内存管理机制。

1. 内存操作

(1)原生内存管理操作符
  • new / new[]:分配堆内存 + 自动调用对象构造函数,new 对应单个对象,new [] 对应对象数组。

  • delete / delete[]:调用对象析构函数 + 释放堆内存,必须与 new /new [] 配对使用,不可混用。

(2)标准库算法(<algorithm>

替代 C 语言的 mem 系列函数,适用于非平凡对象(有构造 / 析构函数的类对象),保证类型安全:

  • std::copy(standard copy,区间拷贝):将指定区间的元素拷贝到目标位置,对应 C 语言的 memcpy,但支持对象的拷贝构造。

  • std::fill(standard fill,区间填充):将指定区间的所有元素赋值为指定值,对应 C 语言的 memset,但类型安全,可用于任意类型。

(3)底层内存工具(<memory>
  • std::uninitialized_copy:在未初始化的内存上构造并拷贝对象,多用于容器底层实现,日常开发较少直接使用。

2. 字符串操作:std::string(<string>

std::string自动管理内存、动态扩容,无需手动处理'\0',提供了完整的增删改查接口。

(1)构造与赋值
  • 默认构造:std::string s;生成空字符串

  • C 串构造:std::string s("hello");用 C 风格字符串初始化

  • 重复字符构造:std::string s(5, 'a');生成 5 个 ‘a’ 的字符串

  • 拷贝构造:std::string s2(s1);复制另一个字符串

  • assign(赋值)成员函数:支持按位置、长度截取赋值,用法灵活。

(2)拼接与追加
  • +=运算符重载:直接追加字符串、字符、C 风格字符串

  • append(追加)成员函数:支持多种重载,可追加子串、重复字符等

  • push_back(尾部压入):追加单个字符

(3)长度与容量
  • size() / length():返回字符串字符个数,二者功能完全等价

  • empty():判断字符串是否为空

  • capacity():返回当前已分配的内存容量

  • reserve():预分配内存容量,减少扩容开销

  • resize():调整字符串长度,超出截断,不足则填充指定字符

(4)字符访问
  • operator[]:下标访问,越界行为未定义,性能更高

  • at():下标访问,越界时抛出std::out_of_range异常,更安全

  • front() / back():访问首尾字符(C++11)

  • c_str():返回以'\0'结尾的const char*指针,用于兼容 C 语言接口

(5)查找、修改与删除(补充完整删除接口)

所有查找函数返回size_t类型的下标,未找到时返回std::string::npos

查找类

  • find():正向查找子串或字符第一次出现的位置

  • rfind():反向查找子串或字符最后一次出现的位置

  • find_first_of():查找字符集中任意字符第一次出现的位置

  • find_last_of():查找字符集中任意字符最后一次出现的位置

修改与删除类

  • substr(sub string,截取子串):返回指定位置、长度的子串,不修改原字符串

  • replace(替换):替换指定区间的内容为新字符串

  • insert(插入):在指定位置插入字符或字符串

  • erase(擦除 / 删除):专属删除函数,支持三种重载:

    1. 删除指定位置开始的指定长度:s.erase(pos, len);

    2. 删除迭代器指向的单个字符:s.erase(iter);

    3. 删除迭代器区间内的所有字符:s.erase(begin_iter, end_iter);

  • pop_back(尾部弹出):删除最后一个字符(C++11)

  • clear(清空):删除所有字符,将字符串置为空,等价于s.erase()

(6)C++17 扩展:std::string_view

只读字符串视图,不持有内存,仅记录指针和长度,用于高效传递字符串,避免无意义的内存拷贝。


关键注意事项

  1. 安全优先:C 语言的 strcpy、strcat 无边界检查,生产环境优先使用带长度限制的 strncpy、strncat,或直接使用 C++ 的 std::string。

  2. strncpy 陷阱:源串长度 ≥ 限制长度时,不会自动补'\0',必须手动设置结束符。

  3. 重叠内存操作:内存区域重叠时,拷贝必须使用 memmove,不能用 memcpy。

  4. 指针失效:std::string 调用 c_str () 返回的指针,在字符串修改、扩容、析构后会立即失效,不可继续使用。

  5. npos 类型:std::string::npos 是无符号 size_t 类型,不要用有符号 int 变量与其比较,避免溢出导致逻辑错误。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/28 12:56:36

ALA算法在无人机动态路径规划中的Matlab实现与优化

1. 项目概述&#xff1a;ALA算法在无人机路径规划中的创新应用2025年算法人工旅鼠算法(Artificial Lemming Algorithm, ALA)是受自然界旅鼠群体迁徙行为启发的新型群体智能算法。与传统的蚁群算法、粒子群优化不同&#xff0c;ALA特别适合解决无人机在复杂环境中的动态路径规划…

作者头像 李华
网站建设 2026/7/28 12:55:56

医学统计方法在文化产业中的跨界应用

1. 当医学统计遇上文化产业&#xff1a;一场跨界思维的对撞 十年前我在三甲医院做临床数据分析时&#xff0c;从未想过那些处理肿瘤生存率的统计方法&#xff0c;有一天会被用来预测网络小说的爆款概率。直到去年参与某视频平台的推荐算法优化项目&#xff0c;当我把Kaplan-Mei…

作者头像 李华
网站建设 2026/7/28 12:55:44

暗黑破坏神2存档编辑器:零门槛Web工具让你重塑庇护所冒险

暗黑破坏神2存档编辑器&#xff1a;零门槛Web工具让你重塑庇护所冒险 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 你是否曾为暗黑破坏神2中角色的某个错误加点而懊悔&#xff1f;是否梦想过测试各种build组合却不想从头练级&…

作者头像 李华
网站建设 2026/7/28 12:51:52

边缘视觉模型数据增强实战:从原理到Jetson Nano优化

1. 从“炼丹”到“炼数据”&#xff1a;为什么视觉模型离不开数据增强在边缘计算设备上部署视觉模型&#xff0c;比如我们手头的Jetson Nano 2GB&#xff0c;开发者最常遇到的瓶颈往往不是推理速度&#xff0c;而是模型精度。你辛辛苦苦训练了一个模型&#xff0c;在自己的测试…

作者头像 李华
网站建设 2026/7/28 12:50:23

幻兽帕鲁存档编辑神器:安全修改游戏数据的完整指南

幻兽帕鲁存档编辑神器&#xff1a;安全修改游戏数据的完整指南 【免费下载链接】palworld-save-tools Tools for converting Palworld .sav files to JSON and back 项目地址: https://gitcode.com/gh_mirrors/pa/palworld-save-tools 你是否曾经因为《幻兽帕鲁》的存档…

作者头像 李华
网站建设 2026/7/28 12:49:20

GEO优化关键词怎么选?广拓时代提醒小企业别只盯大词

很多小企业做GEO优化时&#xff0c;一上来就想做行业大词。 比如做装修的想做“装修公司”&#xff0c;做财税的想做“代理记账”&#xff0c;做营销的想做“AI营销”。这些词当然重要&#xff0c;但对小企业来说&#xff0c;未必是最容易见效的入口。 AI搜索里的关键词选择&am…

作者头像 李华