为什么堆分配存储串会出现部分代码不执行的问题(主函数main内容未执行完就跳出),求讲解,附上代码(c)

问题描述:

img


#include <stdio.h> 
#include <stdlib.h>

#define OK     1
#define ERROR   0
#define OVERFLOW  -2

typedef int Status;
//定义结构体 
typedef struct HString{
    char *ch;    
    int length; //串长度 
}HString;

//-----------各项基本函数原型-------------
Status StrAssign(HString &T,char *chars);//生成一个其值等于串常量chars的串T 
Status StrLength(HString S);            // 返回S的元素个数; 
Status StrCompare(HString S,HString T);// 若S>T.则返回值>0; 若S=T.则返回值=0; 若S<T.则返回值<0; 
Status ClearString(HString &S);        //将S清为空串,并释放内存
Status Concat(HString &T,HString S1,HString S2);//用T返回S1+S2 
Status SubString(HString S,int pos,int len);//返回串S第pos个字符起长度为len的字串

// ---------------主函数------------------
int main(){
    char chars01[]="123456"; 
    HString str1;
    printf("---生成字符串str1并返回i的值:---\n");
    StrAssign(str1, chars01);
    printf("-------字符串str1的长度:%d-------\n",StrLength(str1));
    
    char chars02[]="654321"; 
    HString str2;
    printf("---生成字符串str2并返回i的值:---\n");
    StrAssign(str2, chars02);
    printf("-------字符串str2的长度:%d-------\n",StrLength(str2));
    printf("----字符串str1和str2的比较结果:%d----\n",StrCompare(str1,str2));
} 


//---------------函数的定义--------------- 
//生成一个其值等于串常量chars的串T
Status StrAssign(HString &T,char *chars){
    if(T.ch){
        free(T.ch);
    } 
    int i=0;
    for(char *c = chars; *c; ++c, ++i){
    }
    if(!i){
        T.ch=NULL; T.length=0;
    }else{
        T.ch=(char*)malloc(i*sizeof(char));
        if(!(T.ch)){
            exit(OVERFLOW);
        }
        for (int j = 0; j < i; j++){
            T.ch[j] = chars[j];
        }
        T.length = i;        //T.length=i;
    }
    printf("-----------i的值为:%d-----------\n",i);
    return OK;
}
// 返回S的元素个数; 
Status StrLength(HString S){
    return S.length;
}
// 若S>T.则返回值>0; 若S=T.则返回值=0; 若S<T.则返回值<0; 
Status StrCompare(HString S, HString T)
{
    for(int 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;//如果全部相等,则返回字符串长度之差
}
//将S清为空串,并释放内存
Status ClearString(HString &S){
    if(S.ch){
        free (S.ch);
        S.ch=NULL;
    } 
    S.length=0;
    return OK;
}
//用T返回S1+S2 
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)){
        exit(OVERFLOW);
    }
    int i=0;
    for(i;i<S1.length+S2.length;i++){
        T.ch[i]=S1.ch[i];
    }
    for(int j=0;j<S1.length+S2.length;i++,j++){
        T.ch[i]=S2.ch[i];
    }
    T.length=S1.length+S2.length;
    return OK;
}
//返回串S的第pos个字符起长度为len的子串
Status SubString(HString &sub, HString S, int pos, int len)
//1<=pos<<StrLength(S)且0<=len<=StrLength(S)-pos+1
{
    if (sub.ch){
        free(sub.ch);
    } 
    if (len == 0){
        sub.ch = NULL;
        sub.length = 0;
    }
    else{
        if (pos >= 1 && pos <= S.length&&len > 0 && len <= S.length - pos + 1)
        {
            sub.ch = (char *)malloc(len*sizeof(char));//为子串分配空间
            if (!sub.ch)exit(OVERFLOW);
            for (int i = 0; i < len; i++, pos++)//将相对应的字符传给子串
                sub.ch[i] = S.ch[pos-1];
            sub.length = len;
            return OK;
        }
    }
     return ERROR;
}

出问题的原因是定义HString str1,str2的时候,没有设置str1.ch,str2.ch为空,在StrAssign函数一开始检查ch是否为空,不为空调用free释放。但如果不设置为空,会是一个垃圾值,free时崩溃了
简单的解决办法是给结构增加一个构造函数,进行指针初始化就行了

typedef struct HString{
    char *ch;    
    int length; //串长度 
HString()
{
      ch  = NULL;
      length  = 0;
}
}HString;