簡體   English   中英

為什么在此處覆蓋字符串文字(C++)?

[英]Why is a string literal being over written here (C++)?

我有一個 class 持有一個指針。 我在這里只包含了骨架代碼。 class 構造函數需要一個字符串。

#include <iostream>
#include <string>

using namespace std;

class slice {
public:
slice(string s):
    data_(s.data()),
    size_(s.size()) {}

    const string toString() {
        string res(data_, data_+size_);
        return res;
    }

private:
    const char* data_;
    const size_t size_;
};

int main() {

    slice a{"foo"};
    slice b{"bar"};


    cout << a.toString() << endl;
    cout << b.toString() << endl;
}

該程序的output為:

$ g++ test.cpp && ./a.out 
bar
bar

我期待

foo
bar

這里發生了什么? object a 持有的指針如何被覆蓋?

這里發生了什么? object a 持有的指針如何被覆蓋?

您正在經歷未定義的行為

slice(string s):
    data_(s.data()),
    size_(s.size()) {}

這里string s是輸入字符串的副本,並在構造函數的持續時間內存在。 因此s.data()在構造函數完成后懸空。

a 和 b 是從臨時字符串對象創建的。 當這些字符串對象在語句結束時被銷毀時,它們會釋放它們的 memory,並且指向字符所在位置的底層 char* 變得無效。 您通常不能使用從這樣的字符串中獲取的 char* 。

std::string對象在超出 scope 時調用其析構函數std::~string()

slice(string s) : data_(s.data()), size_(s.size()) {
    // After this function is called, the string goes out of scope and s.data() is deallocated by the destructor.
    // Leaving gibberish value inside of 'data_' member
}

之后,當您實際打印該值時, data_到那時已經被銷毀,然后您對它所做的事情會導致未定義的行為(這意味着輸出字符串時程序的行為可以是任何東西,因此術語undefined )。


因為這個問題已經回答了。 我不妨給出一個合理的解決方案。

解決方案:創建一個臨時保存在 class 中的字符串的副本,並在 class 超出 scope 時將其銷毀:

例子:

class slice {
public:
    slice(string s):
        size_(s.size()) {
        // Dynamically allocate a new string so that it doesn't get deleted when it goes out of scope
        data_ = new char[s.size()];
        // Copy the data into the newly allocated string
        s.copy(data_, s.size());
    }

    slice(const slice&) = default; // Copy constructor
    slice(slice&&) = default;      // Move constructor

    // Destructor
    ~slice() {
        delete[] data_;
    }

    const string toString() {
        // Now 'data_' retains its value even after the string is destroyed
        string res(data_, data_+size_);
        return res;
    }

private:
    char* data_;
    const size_t size_;
};

暫無
暫無

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

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