2010-01-24 41 views
7

tengo este códigoequivalente de C++ para memset en char *

char * oldname = new char[strlen(name) + 1]; 

    memcpy(oldname,name,strlen(name) + 1); 

    name = new char[strlen(oldname) + strlen(r.name) + 1]; 
    memset(name, '\0', strlen(name)); 

    strcat(name,oldname); 
    strcat(name," "); 
    strcat(name,r.name); 

entiendo que es un no, no utilizar memcpy y memset pero no he entendido muy bien cómo utilizar esto en C++, preferiblemente sin std.

¿Alguien sabe? Gracias.

+1

Parece que puede haber asignado un personaje demasiado poco para el nombre. Y no veo por qué llenas la matriz con ceros en primer lugar, si luego la sobreescribes. (El primer strcat solo requiere que el primer carácter sea nulo, strcpy no requeriría ni siquiera eso. Ambas funciones anulan la cadena por ti). Ah, y 'strlen (name)' no funcionará muy bien, a menos que el ¡la cadena ya contiene una cadena de caracteres terminada correctamente! No hace más que contar todos los caracteres hasta el primer carácter nulo. – UncleBens

Respuesta

-1
char * oldname = new char[strlen(name) + 1]; 

    //memcpy(oldname,name,strlen(name) + 1); 
    strcpy(oldname,name); 

    name = new char[strlen(oldname) + strlen(r.name) + 1]; 
    //memset(name, '\0', strlen(name)); 
    name[0] = '\0'; 

    strcat(name,oldname); 
    strcat(name," "); 
    strcat(name,r.name); 

entiendo esto ahora, sólo quería pegar este código para todos los futuros visitantes Las líneas comentadas son equivalentes a los que sin comentar por debajo de ellos. C comentó, C++ sin comentario.

+0

que está mal. la línea comentada no es equivalente al nombre [0] = '\ 0' –

7

Una posible sustitución para memset cuando tiene una matriz de tipos de objetos es utilizar el algoritmo std::fill. Funciona con rangos de iteradores y también con punteros en matrices.

memcpy las llamadas generalmente se pueden reemplazar con llamadas al std::copy.

p. Ej.

std::copy(name, name + strlen(name) + 1, oldname); 
// ... 
std::fill(name, name + strlen(name), '\0'); 

memsetmemcpy y aún están allí y se puede utilizar en su caso, sin embargo. Es probable que sea un no-no más grande desde el punto de vista de muchos desarrolladores de C++ al usar un new sin formato y sin usar un objeto de administración de recursos. Es mucho mejor usar un std::string o un std::vector<char> para que la desasignación de memoria sea automática y el código sea más seguro a excepción de excepciones.

+2

'std :: fill_n' podría ser una mejor coincidencia que llenar. De lo contrario, buena respuesta, +1 :) – jalf

1

Si solo está haciendo la manipulación de cadenas, use una cadena.

2

entiendo que es un no, no usar memcpy y memset pero no he Entendí exactamente cómo usar esto en C++, preferiblemente sin std.

No es un no-no utilizar memcpymemset y cuando su uso sea apropiado. ¿Por qué debería ser?

Hay std::copy en C++ que copia un conjunto de elementos (funciona en cualquier tipo y no solo en char*) de un iterador a otro.

+0

¿Pero es el uso apropiado cuando puede ser reemplazado por el más seguro y potencialmente más eficiente 'std :: fill'? – jalf

+1

@jalf: no hay duda de que 'std :: fill' debe preferirse a' memset' en general * cuando se puede usar *. Mi punto era que generalmente no hay una función de idioma que descartarás por completo. Un ejemplo es una pieza de código que debe compilarse en C y en C++. –

2

Aparte de la inconveniencia de tener que copiar manualmente y hacer toda la asignación de memoria usted mismo, no hay nada de malo en ese código C++.

Sin embargo, recomendaría encarecidamente el uso de std::string para la manipulación de cadenas en C++.

1

Para copiar de aa b, tome std::copy(src_start,src_end,dest_start), que incrementa src_start y lo copia al siguiente elemento de destino hasta que se cumpla src_start==src_end.

memcpy(oldname,name,strlen(name)+1) 
// is the same as 
std::copy(name,name+strlen(name)+1,oldname) 

.. excepto que también funcionará para los no-POD, y usted no necesita meterse con longitudes de bytes si un solo elemento es más de un byte.

Sin embargo, si solo desea realizar la manipulación de cadenas, se proporcionan la clase std::string (y std::wstring para cadenas de caracteres anchas). La concatenación de ellas es tan simple como:

std::string s = "name",s2 = ..,s3 = ..; 
s = s2+s+s3+"Hello"; 

Nada le impide el uso de la familia de funciones en C++ strxxx, pero recomiendo encarecidamente que cambie a std::string y resto de la STL. Tampoco es perfecto, pero mucho menos propenso a errores.