Будет ли std :: basic_string уничтожать нулевое завершение каждый раз? - PullRequest
3 голосов
/ 07 апреля 2020

Недавно я обновил свой компилятор с g cc -4.3.x до g cc -7.x, а затем встретил исключение Assert для одного из моих тестеров.

Код выглядит следующим образом :

struct data {
    data() : _c(0) { ++CREATED; std::cout<<"data  CREATED +1"<<_c<<" addres: "<<&_c<<std::endl;}
    data(char c) : _c(c) { ++CREATED; std::cout<<"data  with C CREATED +1"<<_c<<std::endl;}
    data(const data& rhs) : _c(rhs._c) { ++COPIED; }
    ~data() { ++DESTROYED; std::cout<<"data  DESTROYED +1"<<_c<<std::endl;}

    char _c;

    static size_t CREATED;
    static size_t COPIED;
    static size_t DESTROYED;
};

size_t data::CREATED   = 0;
size_t data::COPIED    = 0;
size_t data::DESTROYED = 0;

void testStringReferenceCopiable() {
    typedef std::basic_string<data> data_str;
    std::cout<<"1"<<std::endl;
    data d[] = {'a', 'b', 'c'};
    std::cout<<"2"<<std::endl;
    data_str s( &d[0], 3 );
    std::cout<<"3"<<std::endl;
    data_str s2 = s;
    std::cout<<"4"<<std::endl;
    data_str s3;
    std::cout<<"5"<<std::endl;
    s3 = s;
}

Для gcc7.x вывод выглядит следующим образом:

1
data(char c) CREATED +1a
data(char c) CREATED +1b
data(char c) CREATED +1c
2
data()  CREATED +1
~data()  DESTROYED +1
3
data()  CREATED +1
~data()  DESTROYED +1
4
data()  CREATED +1
~data()  DESTROYED +1
5
data()  CREATED +1
~data()  DESTROYED +1
~data()  DESTROYED +1c
~data()  DESTROYED +1b
~data()  DESTROYED +1a

Для версии gcc4.3.x вывод:

data  CREATED +1
1
data  with C CREATED +1a
data  with C CREATED +1b
data  with C CREATED +1c
2
3
4
5
data  DESTROYED +1c
data  DESTROYED +1b
data  DESTROYED +1a

data  DESTROYED +1


В основном я Можно понять, почему он вызывает Construct of data () каждый раз, может из-за нулевого терминатора. Но я не могу понять, почему он вызывает метод данных деструктора каждый раз. Кто-нибудь может дать мне ответ?

Спасибо!

1 Ответ

3 голосов
/ 07 апреля 2020

G CC 5 изменено std::basic_string, чтобы соответствовать нескольким новым требованиям, которые были введены в C ++ 11.

Изменение, которое вы заметили, заключается в том, что «копирование при записи» было прекращено для std::basic_string в G CC 5. То есть копии одной и той же строки должны быть разными, а не просто подсчитанными ссылками.

...