2013-07-11 21 views
5

Biraz temel okuma yaptım ve topladığımdan .c_str() her zaman boş bir sonlandırıcıya sahip.C++ memcpy to char * from c_str

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; 
} 

ben (benim dize gelen uzunluğunda kısa olması şartıyla) benim değişkene boş sonlandırılmış dize üzerinden kopyalama sağlamak memcpy Will:

Ben oldukça basit bir C++ program var?

+1

Evet ait strcpy, kullanmalıdır 'c_str()' boş sonlandırılmış her zaman, ama bu iş için herhangi bir neden yoktur? – chris

+3

Neden bunu yapıyorsun? Std :: string'in birincil güçlü yönlerinden biri, * char * 'ın bu gibi ham dizileri kullanmasıdır. –

+3

Bu arada, 'size()' veya 'length()' size sabit bir zaman boyutu kazandıracak, strlen() ise lineerdir. – chris

cevap

3

memcpy dize nedir bilmiyor. kopyalamak için bir aralık verirsin.

2

Evet, bu, from'daki dizeniniz 20'den kısa olduğu sürece çalışacaktır. Oh, hayır, bekle, ayrıca NULL sonlandırıcıyı da kopyalayarak 19'dan daha kısa olması gerekir. Sanırım bunun nasıl yönlendirileceğini görüyorsunuz bazı karışıklık için.

Bu kodun neden bu kadar tehlikeli olmasının nedeni budur: Bunun bir demo kodu olduğunu varsayar ve gerçek kodunuz bu dizeyi bir tür girdiden alır. O anda ne kadar süre olduğunu kontrol edemeyeceksin. Bunu kısaltabilirsiniz ama bunu yapmayı unutmuş olabilirsiniz, bu da programınızın içeriği muhtemelen kendisine ait olmayan belleğe kopyalayacağı anlamına gelir. Bu, başka önemli verileri içerebilecek bir belleğin üzerine yazarken, en azından tanımlanamayan bir davranışın çökmesine yol açabilir.

string sınıfını kullanmak, dize uzunluğunu belirtmek zorunda kalmadan bu tür sorunlardan kaçınmanıza yardımcı olur. Bu sınıfı kullanmanızı öneriyorum ve sadece kesinlikle gerekli olduğunda c_str()'u içeren işlemleri yapın.

0

Sonlandırma noktasını sağlamak için burada strlen'a bağlıdır. Sorunuzun yanıtı "evet" dir (dizinin yeterince büyük olması koşuluyla, bir doğrulama adımı koymanız gerekir). Bunu gerçekten yapmak istiyorsanız

, yapabileceğiniz:

sürece başka yazmıyorsun olarak güvenlidir
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; 
} 

, uzun dize

3

Sen hiç std::string kullanmalıdır "den" haline dizeleri kopyala. bunu böyle yapmak istiyorsanız Ancak, beri yerine 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; 
}