这是串的第二种存储方式,它以一组地址连续的内存单元存放字符串的字符序列,但它们的存储空间是在程序执行过程中动态分配而得。在C语言中,存在一个称之为“堆”的自由存储区,并由C语言的动态分配函数malloc()和free()管理。利用函数malloc()为每个新产生的串分配一块实际串长所需的存储空间,若分配成功,则返回一个指向起始地址的指针,作为串的基址。
//---------------------------------------------------------------------------------------
typedef struct {
char * ch; //若是非空串,则按串长分配存储区,否则,ch为NULL
int length; //表示串长
}HString;
//---------------------------------------------------------------------------------------
以下为该类型串的基本操作。
typedef struct HString{
char *ch; //若是非空串,则按串长分配存储区,否则ch为空
int length; //串长度
HString(){//默认构造函数
ch=NULL;
length=0;
}
}HString;
Status StrAssign(HString &T,char *chars){
if(T.ch) free(T.ch);
int i=0;
char *c=NULL;
for(c=chars;*c!='\0';++c){
++i;
}
if(!i){
T.ch=NULL;
T.length=0;
}else{
T.ch=(char*)malloc(i*sizeof(char));
if(!T.ch) return ERROR;
for(int j=0;j<i;++j){
T.ch[j]=chars[j];
}
T.length=i;
}
return OK;
}
void DisHString(HString s){
cout<<"the string is ";
for(int i=0;i<s.length;++i){
cout<<s.ch[i];
}
cout<<endl<<"and length is "<<s.length<<endl<<endl;
}
int StrCompare(HString s,HString t){
int i;
for(i=0;i<s.length&&i<t.length;++i){
if(s.ch[i]!=t.ch[i]) return s.ch[i]-t.ch[i];
}
return s.length-t.length;
}
Status ClearString(HString &s){
if(s.ch){
free(s.ch);
s.ch=NULL;
}
s.length=0;
return OK;
}
Status Concat(HString &t,HString s1,HString s2){
if(t.ch) free(t.ch);
t.ch=(char*)malloc((s1.length+s2.length)*sizeof(char));
if(!t.ch) return ERROR;
for(int i=0;i<s1.length;++i){
t.ch[i]=s1.ch[i];
}
for(int i=0;i<s2.length;++i){
t.ch[s1.length+i]=s2.ch[i];
}
t.length=s1.length+s2.length;
return OK;
}
int main()
{
char c[5]="abcd";
char d[6]="efghi";
HString t,s1,s2;
StrAssign(s1,c);
StrAssign(s2,d);
Concat(t,s1,s2);
DisHString(s1);
DisHString(s2);
DisHString(t);
return 0;
}
总结:
真是应该好好吐嘈一下,本以为很简单的一段程序居然捣鼓了这么长时间。原理很简单,思路很清晰,绝大部分代码很快就写完了,操作s1没有问题,后面在操作s2就会报一个segment fault (core dumped)的错误(点击打开链接),纠结了很久才把它解决掉。定义指针后可以不初始化,但实际上这个指针中已经有一个值了(就是分给这个指针变量的地方内存中原来的值,假设是0x1234),但是在使用前一定要初始化,否则就是去操作0x1234这个地方的内容,就会出问题,因为不知道0x1234所指的地方是什么内容,如果是段系统代码,就有可能毁坏系统,或者出现其他问题。s2.ch就不为空,但是不知道它表示什么内容,执行free()操作就会报错。在HString 结构体中加一个默认构造函数,将对象的ch全部置空,问题解决。