C语言String结构体,模仿Java的String类(三)

本文继上篇介绍C语言String结构体,讲解如何编写释放内存的函数,确保malloc分配的内存得到正确回收。此外,还讨论了如何创建空字符串以及判断String结构体是否为空的方法,以增强代码的可读性和安全性。
摘要由CSDN通过智能技术生成

在(二)中我们介绍了如何构建一个String结构体,本篇文章中,我们在继续编写几个函数,让String结构体能尽快的被使用起来。

有了构建,那么就应该有释放,因为我们的构建结构体中,使用了malloc函数,因此我们必须编写对应的释放函数,使其在堆上的内存能够被回收。

先介绍一下malloc函数:使用malloc函数需要引入stdlib.h(c语言标准库头文件)。

malloc函数(memory allocation),又称动态内存分配。用于申请一块连续的指定大小的内存块区域,以void*类型返回分配的内存区域地址。当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到malloc函数,且分配的大小就是程序要求的大小。

malloc函数原型为:void *malloc(unsigned int size)。其作用是在内存的动态空间中分配一个长度为size的连续空间。此函数的返回值是分配区域的起始地址,或者说,此函数是一个指针型函数,返回的指针指向该分配域的开头位置。如果malloc函数分配成功则返回指向被分配内存的指针(此空间中的初始值不确定),否则返回空指针NULL

当通过malloc函数分配的内存不在使用时,应使用free()函数将其释放。

我们编写释放String结构体的函数:

/**
 * 释放String结构体所占用的堆空间
 * 同时也会释放结构体内char* value指向的堆空间
 */
void free_string(String* str){
    if(str != NULL){
        if(str->value != NULL){
            free(str->value);
            str->value = NULL;
        }
        free(str);
        str = NULL;
    }
}

首先判断str结构式是否为NULL,当其不为NULL时,我们先释放String结构体中的value,因为其也是用malloc申请的,接着释放str,都是调用free函数,把对应的指针传递进去即可。

在释放完成后,我们显示的把str->value和str都设置为NULL,这是一个好习惯。这样做的好处是:

  1. 避免悬空指针错误:如果后续不小心再次使用该已被释放的指针,可能会导致程序崩溃或出现难以预料的错误。将其设置为 NULL 后,若不小心再次使用,程序更容易检测到这种错误,因为访问 NULL 通常会引发明确的异常或错误提示。
  2. 提高代码可读性和可维护性:明确表明该指针已经不再指向有效内存,让其他开发者或后续维护代码的人能更清楚地理解其状态,减少因误解而产生的潜在问题。

有时需要快速的创建一个结构体,为了节省内存,我们只给结构体中的value一个空字符串(\0)即可。编写String* build_empty_string(void):

/**
 * 创建一个空字符串的结构体
 */
String* build_empty_string(void){
    char emp[1] = {'\0'}; // 创建一个空字符串
    String* empstr = build_string(emp); // 构建空字符串的结构体
    return empstr;
}

为了判断一个String结构体是否是一个空字符串,我们编写bool is_empty(String* str)函数:

/**
 * 判断字符串是否为空串
 * 字符串
 * @param str 字符串结构体指针
 * @return 字符串是否为空 true:空串 false:非空串
 */
bool is_empty(String* str){
    
    if(str == NULL){
        return true;
    }

    if(str->length == 0){
        return true;
    }
    return false;
} 

is_empty的逻辑是,如果str为NULL或者str的length结构体成员的值为0,都认为该String结构体为empty。

这里我们使用了bool,需要引入stdbool.h头文件,它包含了用于定义布尔类型 bool 的宏定义。布尔类型:bool 类型,用于表示真或假。其Linux下的源码:

/* Copyright (C) 1998-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by 
the Free Software Foundation; either version 3, or (at your option)  
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of       
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

/*
 * ISO C Standard:  7.16  Boolean type and values  <stdbool.h>
 */

#ifndef _STDBOOL_H
#define _STDBOOL_H

#ifndef __cplusplus

#define bool    _Bool
#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
#define true    ((_Bool)+1u)
#define false   ((_Bool)+0u)
#else
#define true    1
#define false   0
#endif

#else /* __cplusplus */

/* Supporting _Bool in C++ is a GCC extension.  */
#define _Bool   bool

#endif /* __cplusplus */

/* Signal that all the definitions are present.  */
#define __bool_true_false_are_defined   1

#endif  /* stdbool.h */

后续,我将陆续介绍String结构体下的各函数的实现,以及如何使用String结构体。

敬请期待。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会C、Java多种开发语言的金哥

您的鼓励是我创作的动力源泉!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值