2013-07-11 28 views
5

Ho fatto un po 'di lettura di base e da quello che ho raccolto .c_str() ha sempre un terminatore nullo.C++ memcpy to char * da c_str

Ho un abbastanza semplice programma in C++:

int main(int argc, char** argv) 
{ 
    std::string from = "hello"; 
    char to[20]; 
    memcpy(to, from.c_str(), strlen(from.c_str())+1); 
    std::cout<< to << std::endl; 
    return 0; 
} 

Sarà che memcpy garantire che copio su una stringa con terminazione null alla mia variabile (a condizione che la mia stringa da è più corta di lunghezza)?

+1

Sì, dal momento che 'c_str()' è sempre nullo-terminata, ma non v'è alcun motivo particolare per fare questo? – chris

+3

Perché stai facendo questo? Uno dei principali punti di forza di std :: string è * non * che utilizza matrici raw di char come questa. –

+3

A proposito, 'size()' o 'length()' otterrà una dimensione temporale costante, mentre 'strlen()' è lineare. – chris

risposta

3

memcpy non sa cos'è una stringa. gli dai un intervallo da copiare. dipende da strlen qui per fornire il punto di terminazione dell'intervallo

2

Sì, questo funzionerà finché la stringa in from è più corta di 20. Oh, no, aspetta, stiamo anche copiando il terminatore NULL in modo che debba essere inferiore a 19. Immagino tu veda come ciò può portare con una certa confusione.

Quale è esattamente la ragione per cui questo codice è pericoloso: sto assumendo che questo sia il codice demo e il codice effettivo otterrà quella stringa da una sorta di input. In quel momento non sarai in grado di controllare quanto è lungo. Puoi troncarlo ma potresti dimenticarti di farlo, il che significa che il tuo programma copierà il contenuto nella memoria che probabilmente non gli appartiene. Ciò potrebbe portare a un arresto anomalo, ma almeno a un comportamento indefinito mentre si sovrascrive la memoria che potrebbe contenere altri dati importanti.

Utilizzare la classe string in realtà aiuta a evitare tali problemi non dovendo specificare la lunghezza della stringa. Suggerirei di usare questa classe e fare solo operazioni che coinvolgono c_str() quando assolutamente necessario.

0

La risposta alla tua domanda è "sì" (a condizione che l'array di caratteri sia sufficientemente grande, è necessario eseguire un passaggio di verifica).

Se si vuole veramente fare questo, si può fare:

int main(int argc, char** argv) 
{ 
    std::string from = "hello"; 
    char* to = new char[from.length() + 1]; 
    memcpy(to, from.c_str(), from.length() + 1); 
    std::cout<< to << std::endl; 
    delete[] to; 
    return 0; 
} 

che è più sicuro finché non si sta scrivendo un altro, stringa più lunga in "a"

3

si dovrebbe usare std::string per copia le stringhe. Tuttavia, se si vuole fare in quel modo si dovrebbe usare strcpy invece di memcpy

int main(int argc, char** argv) 
{ 
    std::string from = "hello"; 
    char to[20]; 
    strcpy(to, from.c_str()); 
    std::cout<< to << std::endl; 
    return 0; 
}