string jako tablica znaków - char * p

string jako tablica znaków - char * p
L2
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 3 lata
  • Postów:5
0

Witam,
moje pytanie jest związane z takim oto dziwnym programem (w zasadzie funkcją - nie pytajcie skąd się wzięła):

Kopiuj
string kopiuj (string t) {
    char * p;
    for (int i = 0; i < t.length(); i++) {
        p[i] = t[i];
    }
    return p;
}

Program działa, ale zdaję sobie sprawę, że nie jest on poprawnie napisany - chodzi o to, że nie podaję długości tablicy znaków char * p, co wiąże się z tym, że nie wiadomo gdzie się ona kończy - teoretycznie może się ciągnąć w nieskończoność (poprawcie mnie jeśli nie mam racji). Podejrzewam również, że kompilator "domyśla się" na podstawie analizy pętli for, gdzie kończy się łańcuch p, po czym wstawia na jego końcu znak NULL.

Powiedzcie, czy waszym zdaniem jest to bezpieczne rozwiązanie, czy też może spowodować UB?
Jak można by inaczej kopiować nieznaną liczbę znaków z wejściowego stringa?

MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:7 dni
  • Lokalizacja:Warszawa
  • Postów:1454
4

UB jak nic.
Poza tym kombinacje z d**y wzięte o ile te stringi to są std::string, bo tym można zrobić bez żadnych cudactw string1 = string2;


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
4

@luque212 ty sobie robisz jaja? :D Przecież nie zaalokowałeś tam żadnej pamięci tylko nadpisujesz pamięć na którą przypadkiem pokazuje ten twój wskaźnik. Jak wpiszesz więcej znaków to wywali się z segfaultem. Przy odrobinie wprawy można by ten program exploitować.

nieznaną liczbę znaków z wejściowego stringa?

Serio? Nieznaną? A length tego stringa to co ci zwraca? char * p = new char[t.length()+1]


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
WY
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 3 lata
  • Postów:134
0

Po co taka funkcja w ogóle skoro istnieje coś takiego jak string::c_str ?
Ktoś ładnie popłynął..

http://cpp.sh/5lq3d

edytowany 1x, ostatnio: wyebani
tajny_agent
c_str() niczego nie kopiuje
Delor
Both string::data and string::c_str are synonyms and return the same value.
WY
istnieje jeszcze strcpy
WY
aha, funkcja zwraca stringa a nie char *. To nie ważne...
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:3 minuty
3

To, że ta funkcja nie wykrzacza się od razu, to po prostu niefart. Wystarczy zmiana komputera/kompilatora, albo po prostu inna historia działania aplikacji, a będzie 100% SEGFAULT.
A nawet pomijając zawartość funkcji i jedynie biorąc pod uwagę argument i wartość zwracaną, to autor chyba był nieźle najarany, bo ta funkcja nie daje żadnej funkcjonalności (nawet po naprawieniu), której std::string nie ma.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
Shalom
Ha, nie zauważyłem nawet że ta funkcja zwraca stringa i tak :D Myślałem że zwraca char* i stąd takie dziwne machinacje.
MasterBLB
Chyba mamy nawet kandydata do perełek.
MO
To bardzo dobry kawałek kodu do pytań na rozmowach rekrutacyjnych :) "Powiedz bez zmiany kodu co tu jest źle... i co jeszcze?... I jak byś go zmienił?" A że to perła, bez "dw_u_ch zdań" :>
OD
  • Rejestracja:prawie 6 lat
  • Ostatnio:prawie 6 lat
  • Postów:6
0

std::string zawsze posiada znaną liczbę znaków. Masz na mysli "zmienna" liczbę znaków ?

Ta funkcja nie ma sensu, nie dodaje zadnej nowej funkcjonalnosci. Implementacja rowniez jest bledna i po prostu masz fart ze zadzialalo. Zmien kompilator albo opcje optymalizacji i jest duza szansa ze wywali Ci segmentation fault.

au7h
  • Rejestracja:ponad 11 lat
  • Ostatnio:około rok
  • Postów:215
0

a wystarczyło napisać:

Kopiuj
auto p = std::make_unique<char[]>(t.length()+1);

...
return p.get();
Zobacz pozostałe 6 komentarzy
Delor
Yyy nie załapałem żartu :/
Delor
Jakby rozwinąć ... 'Kopiowanie std::string przez chmurę w Azure.' to już brzmi jak temat na inżynierkę.
Azarien
@Delor: jak na temat na inżynierkę to jest ze 3 razy za krótki :-)
Delor
To się przekopiuje trzy std::string. ;p (Najwidoczniej słowo 'prawie' wykasowałem. Początkowo tam było.)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.