由浅入深C系列三:strcat函数源码分析,到底是连接,还是复制?

简介: strcat函数源码分析,到底是连接,还是复制?

困惑起源

最近在review一段功能代码,看到如下一段。对于strcat部分,在调用后即进行了free操作,会不会有问题,strcat不是把字符串连接上去么?

char* all_field_name = (char*)malloc(sizeof(char)*1024);
memset(all_field_name, 0, 1024);
// ... 省略部分
while (myfields = sql_fetch_field(my_res)) 
{
    char* field_name = (char*)malloc(sizeof(char)*(strlen(myfields->name)+4));
    sprintf(field_name, "| %s ", myfields->name);
    strcat(all_field_name, field_name);
    free(field_name);
}
free(all_field_name)

读源码,解困惑

解决困惑的最好办法,就是查看源代码,看看这个常用库函数到底是怎么操作的。以下代码来源于\linux-6.1-rc1\lib\string.c

#ifndef __HAVE_ARCH_STRCAT
/**
 * strcat - Append one %NUL-terminated string to another
 * @dest: The string to be appended to
 * @src: The string to append to it
 */
char *strcat(char *dest, const char *src)
{
    char *tmp = dest;

    while (*dest)
        dest++;
    while ((*dest++ = *src++) != '\0')
        ;
    return tmp;
}
EXPORT_SYMBOL(strcat);
#endif

通过这段代码走读,函数主要的实现步骤如下:
1、函数实现代码的第一行声明了一个很重要的 tmp指针,保留目的字符串的起始地址。接着就可以放心的使用dest,dest要一直指向目的字符串的串尾,才能保证后面把源串连接过来。
2、接着通过一个循环,找到了目的字符串的串尾,即以\0结尾的位置。这个也提醒我们,如果要执行字符串连接,以\0结尾很重要,否则会coredump。
3、将源字符串一个一个的copy了过来。并不是将源字符串直接连接到目的字符串的串尾。

结论

到这里,就比较清楚的看出来,strcat其实是把源字符串复制到目的字符串的串尾来实现“连接”的功能。

相关文章
|
6月前
|
C语言
c语言进阶部分详解(经典回调函数qsort()详解及模拟实现)
c语言进阶部分详解(经典回调函数qsort()详解及模拟实现)
69 0
|
6月前
|
算法 编译器 C++
【C++ 函数 基本教程 第二篇 】深度剖析C++:作用域与函数查找机制
【C++ 函数 基本教程 第二篇 】深度剖析C++:作用域与函数查找机制
62 0
|
6月前
|
存储 C++
【C++】function包装器全解(代码演示,例题演示)
【C++】function包装器全解(代码演示,例题演示)
字符串的进阶练习案例(接上一节)
字符串的进阶练习案例(接上一节)
49 0
【C知识点】函数地址
【C知识点】函数地址
81 0
|
数据安全/隐私保护
零基础VB教程032期:sub过程与function自定义函数的异同专题精讲
零基础VB教程032期:sub过程与function自定义函数的异同专题精讲
|
数据挖掘 Perl
Mummer 用法简析
Mummer 用法简析
129 0
|
C语言
由浅入深C系列四:memset/memcpy源码分析,为什么这二个函数的目的字符串在前面,源字符串在后面?
memset/memcpy源码分析,为什么这二个函数的目的字符串在前面,源字符串在后面?
|
算法 C++
你是真的“C”——各种实用string类库函数的详细实现过程【上篇】
  哈喽各位友友们😊,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!😘我仅已此文,和大家分享你是真的“C”——各种实用string类库函数的详细实现过程。都是精华内容,可不要错过哟!!!😍😍😍
82 0
源于《剑指offer》经典面试题---库函数atoi如何使用及模拟实现
要求如果遇到空格,则根据需要丢弃可能多的空格字符,直到找到第一个非空字符。
85 0