[C++ Builder] Kopiowanie AnsiString z VCL

0

Przy odpowiadaniu na pewien post zauważyłem
dziwną rzecz w zachowaniu AnsiString z VCL .
Wykonując przypisanie obiektów typu AnsiString ,
następuje gubienie bufora znakowego jednego z nich .

Tworzę obiekt 'a' z jakimś napisem .
Tworzę obiekt 'b' .
Wykonuję przypisanie b = a ;

Modyfikuję napis w obiekcie 'b' .
Okazuje się że dane (napis) zostaje również zmodyfikowany
w 'a' . Co to za jaja .

Kompilator C++ Builder 3 ,program konsola z użyciem VCL .

#include <condefs.h>
#pragma hdrstop
#include <iostream.h>

// Konsola z użyciem VCL
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char **argv)
{

    AnsiString a = "Przykladowy napis" ;

    AnsiString b ;

    cout << "Poczatkowa zawartosc zmiennej 'a' == " << a.c_str() << endl ;
    cout << "Adresy przed kopiowaniem ." << endl ;
    cout << "Adres bufora dla 'a' == "   << (long)a.c_str()<< endl ;
    cout << "Adres bufora dla 'b' == "   << (long)b.c_str()<< endl ;
    cout << endl ;

    b = a ;  // operator przypisania

    cout << "Zapis znaku 'X' do zmiennej 'b' " << endl ;
    b[2] = 'X' ;
    cout << "Teraz zawartosc 'b' == " << b.c_str() << endl ;
    cout << "Teraz zawartosc 'a' == " << a.c_str() << endl ;


    cin.get();

        return 0;
}

Wydruk z programu :

Poczatkowa zawartosc zmiennej 'a' == Przykladowy napis
Adresy przed kopiowaniem .
Adres bufora dla 'a' == 9578472
Adres bufora dla 'b' == 4366986

Zapis znaku 'X' do zmiennej 'b'
Teraz zawartosc 'b' == PXzykladowy napis
Teraz zawartosc 'a' == PXzykladowy napis

STL zachowuje się 'normalnie' ,tzn jeden obiekt nie ma wpływu na drugi .
To wydruk gdy zastąpimy AnsiString VCL typem string z STL :

Poczatkowa zawartosc zmiennej 'a' == Przykladowy napis
Adresy przed kopiowaniem .
Adres bufora dla 'a' == 9584472
Adres bufora dla 'b' == 4330196

Zapis znaku 'X' do zmiennej 'b'
Teraz zawartosc 'b' == PrXykladowy napis
Teraz zawartosc 'a' == Przykladowy napis

Czyli Ok,

0

Obiekt który jest typu AnsiString jest w rzeczywistości wskaźnikiem a ty przez przypisanie utworzyłeś 2 wskaźniki do tego samego miejsca.

0

@Pokemaniak
Proszę Cię nie czytaj moich postów bo wpadam w depresję [green] ,
tu nie ma żadnych wskaźników jawnie tworzonych (oprócz tych wypisywanych na konsolę)...

0

Dziwne, może to ma związek ze źle zaimplementowanym copy-on-write :| ?

0

Nie wiem czy to coś zmienia, ale c_str nie koniecznie zwraca wskaźnik do tego co w AnsiStringu. Może zwracać po prostu adres do innego buforu do którego dodano znak '\0' na końcu.

Check this out:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <condefs.h>
#pragma hdrstop
#include <iostream.h>

// Konsola z użyciem VCL
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char **argv)
{

    AnsiString a = "Przykladowy napis" ;

    AnsiString b ;

    cout << "Poczatkowa zawartosc zmiennej 'a' == " << a.c_str() << endl ;
	cout << "Adresy przed kopiowaniem ." << endl ;
	cout << "a.data == "   << (long)a.data()<< endl ;
	cout << "b.data == "   << (long)b.data()<< endl ;
	cout << "a.c_str == "   << (long)a.c_str()<< endl ;
	cout << "b.c_str == "   << (long)b.c_str()<< endl ;
	cout << "a.data == "   << (long)a.data()<< endl ;
	cout << "b.data == "   << (long)b.data()<< endl ;
	cout << endl ;

	cout << "b = a" << endl ;
	b = a ;  // operator przypisania

	cout << "a.data == "   << (long)a.data()<< endl ;
	cout << "b.data == "   << (long)b.data()<< endl ;
	cout << "a.c_str == "   << (long)a.c_str()<< endl ;
	cout << "b.c_str == "   << (long)b.c_str()<< endl ;
	cout << "a.data == "   << (long)a.data()<< endl ;
	cout << "b.data == "   << (long)b.data()<< endl ;

	cout << "Zapis znaku 'X' do zmiennej 'b' " << endl ;
	b[2] = 'X' ;

	cout << "a.data == "   << (long)a.data()<< endl ;
	cout << "b.data == "   << (long)b.data()<< endl ;
	cout << "a.c_str == "   << (long)a.c_str()<< endl ;
	cout << "b.c_str == "   << (long)b.c_str()<< endl ;
	cout << "a.data == "   << (long)a.data()<< endl ;
	cout << "b.data == "   << (long)b.data()<< endl ;

    cout << "Teraz zawartosc 'b' == " << b.c_str() << endl ;
    cout << "Teraz zawartosc 'a' == " << a.c_str() << endl ;


    cin.get();

        return 0;
}

Ale faktycznie coś jest nie tak, c_str nie dizała do końca dobrze.

0

@_0x666_
Niezłe jaja , W Builder C++ 4 działa poprawnie , wygląda na bug w 3 , szkoda
przywiązałem się do tego kompilatora :> .

@adf88

ale c_str nie koniecznie zwraca wskaźnik do tego co w AnsiStringu

niech będzie , ale faktem jest że w BCB 3 ten program działa niezgodnie
z STL i właściwie zasadami funkcjonowania obiektów w C++ , klapa .

@Pokemaniak
Szkoda mi klawiatury aby Ci odpowiadać....

1 użytkowników online, w tym zalogowanych: 0, gości: 1