C中的字符串追加函数

string Append function in C

我想创建一个字符串附加函数,但是当我想打印该函数时它崩溃了。我调试了它,但我找不到可能是什么问题。

struct string {
    size_t length;
    size_t allocated;
    char* data;
};
string* Init(char* str) {
    string* s = malloc(sizeof(string));
    size_t strLen = strlen(str);
    s->data = (char*)malloc(strLen*2); //allocate 2x of the length
    memcpy(s->data,str,strLen);
    s->data[strLen] = '[=10=]';
    s->length = strLen;
    s->allocated = 2*strLen;
    return s;
}
void AppendBack(string* str, string* new) {
    if(str->allocated < str->length + new->length) { //allocate more
        char* data = (char*)realloc(strGet(str),str->allocated*2);
        str->allocated = str->allocated*2;
        str->data = data;
        if(str->allocated < str->length + new->length) { //need more allocation
            AppendBack(str,new);
        }
    }
    str->length = str->length + new->length;
    for(int i = new->length; i >= 0; --i) {
        str->data[str->length - i] = new->data[new->length - i];
    }
    str->data[str->length] = '[=10=]';
}

int main() {
    string* a = Init("abc");
    string* b = Init("1234fedfsdffghjkjhgfds3ghjk7345678juhzbfsdfsd");
    AppendBack(a,b);
    strPrint(a);
    return 0;
}

编辑代码:

    char* strGet(string* str) {
        return str->data;
    }
    void strPrint(string* str) {
        printf("%s",strGet(str));
    }

很抱歉,我遗漏了部分代码。

您有两个错误:

  1. 您需要为终止零分配一个额外的字节。

  2. 您需要在递归调用 AppendBack 后 return,否则您会损坏字符串。

这是工作代码:

void AppendBack(string* str, string* new) {
    if(str->allocated < (str->length + new->length + 1)) { // NOTE: +1
        char* data = (char*)realloc(str->data,str->allocated*2); // removed call to strGet
        str->allocated = str->allocated*2;
        str->data = data;
        if(str->allocated < (str->length + new->length + 1)) { // NOTE: +1
            AppendBack(str,new);
            return; // NOTE: return here
        }
    }
    str->length = str->length + new->length;
    for(int i = new->length; i >= 0; --i) {
        str->data[str->length - i] = new->data[new->length - i];
    }
    str->data[str->length] = '[=10=]'; // See? You need an extra byte for this
}

我删除了对 strGet 的调用,因为您没有向我们展示该代码。

我认为您没有很好地处理空终止符的分配。您的 length 字段不计算空终止符,因此您的 allocated 字段也不应该,否则您的计算有时可能会关闭。但是您的 malloc() 调用需要考虑空终止符。

此外,您在执行递归后并未退出 AppendBack()。我建议完全摆脱递归,而是在迭代循环中计算所需的分配大小。

试试像这样的东西:

typedef struct string {
    size_t length;
    size_t capacity;
    char* data;
} string;

string* Init(char* str) {
    string* s = (string*) malloc(sizeof(string));
    if (!s) return NULL;
    size_t strLen = strlen(str);
    s->length = strLen;
    s->capacity = strLen*2;
    s->data = (char*) malloc(s->capacity+1); //allocate 2x of the length, plus a null terminator
    if (!s->data) {
        free(s);
        return NULL;
    }
    memcpy(s->data, str, strLen);
    s->data[strLen] = '[=10=]';
    return s;
}

void Cleanup(string* str) {
    if (str) free(str->data);
    free(str);
}

void AppendBack(string* str, string* str2) {
    size_t newLen = str->length + str2->length;
    if (str->capacity < newLen) { //allocate more
        size_t cap = str->capacity;
        do {
            cap *= 2;
        } while (cap <= newLen);
        char* data = (char*) realloc(str->data, cap+1);
        if (!data) return;
        str->data = data;
        str->capacity = cap;
    }
    memcpy(&str->data[str->length], str2->data, str2->length);
    str->data[newLen] = '[=10=]';
    str->length = newLen;
}

void strPrint(string *str) {
    printf("%s", str->data);
}

int main() {
    string* a = Init("abc");
    string* b = Init("1234fedfsdffghjkjhgfds3ghjk7345678juhzbfsdfsd");
    AppendBack(a,b);
    strPrint(a);
    Cleanup(b);
    Cleanup(a);
    return 0;
}