簡體   English   中英

調整char數組的大小並不總是有效

[英]Resizing char array not always working

在名為Str的自定義字符串類中,我具有一個函數c_str() ,該函數僅將私有成員char* data返回為const char* c_str() const { return data; } const char* c_str() const { return data; } 在創建新的Str后調用此方法有效,但是如果我隨后使用cin覆蓋Str ,則僅在某些情況下對其調用c_str() ,但如果我將cin大於原始Str則始終有效。

Str b("this is b");
cout << b.c_str() << endl;

cin >> b;
cout << b.c_str() << endl;

在這里,第一個b.c_str()起作用了,但是如果我嘗試將cin >> b;上的Str b更改為“ b” cin >> b; 行,然后輸出'b'+一點垃圾。 但是,如果我嘗試將其更改為“ bb”,則通常可以使用,並且如果將其更改為比“ this is b”更長的時間,則它始終可以使用。

這很奇怪,因為我的istream運算符(被友好地使用)完全取消了Str分配,並最終為讀取的每個char分配了僅大1個char的新char數組(只是為了查看它是否可以工作,不可以)。 因此,似乎在讀取其他內容后返回數組將返回已設置data的新數組。

相關功能:

istream& operator>>(istream& is, Str& s) {
    delete[] s.data;
    s.data = nullptr;
    s.length = s.limit = 0;

    char c;
    while (is.get(c) && isspace(c)) ;

    if (is) {
        do s.push_back(c);
        while (is.get(c) && !isspace(c));

        if (is)
            is.unget();
    }
    return is;
}

void Str::push_back(char c) {
    if (length == limit) {
        ++limit;
        char* newData = new char[limit];

        for (size_type i = 0; i != length; ++i)
            newData[i] = data[i];

        delete[] data;
        data = newData;
    }
    data[length++] = c;
}

使用這樣的push_back() ,該數組的容量將永遠不會超過其擁有的容量,因此我看不到c_str()如何輸出任何內存垃圾。

基於問題中的push_back()和注釋中的c_str() ,不能保證從c_str()返回的C字符串為空終止。 由於char const*在沒有空終止符的情況下不知道字符串的長度,因此這就是問題的根源!

分配小內存對象時,您可能會找回字符串類先前使用的小內存對象之一,該對象包含非空字符,導致打印的字符看起來好像是找到的第一個空字節的長度一樣。 當分配更大的塊時,您似乎會返回仍然包含空字符的“新”內存,從而使情況看起來好像一切正​​常。

基本上有兩種方法可以解決此問題:

  1. c_str()返回char const*之前,添加一個空終止符。 如果您暫時不關心多線程,可以在c_str()函數中完成。 在多線程很重要的情況下,對const成員函數進行任何更改可能是一個壞主意,因為它們會引入數據競爭。 因此,C ++標准字符串類在一個突變操作中添加了空終止符。
  2. 完全不支持c_str()函數,而是為您的字符串類實現輸出運算符。 這樣,不需要空終止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM