2012-07-04 13 views
5

Escribo una clase de cadena que es similar a std :: string para una tarea de tarea, pero no puedo encontrar la forma de devolver una cadena de caracteres que no provoque una pérdida de memoria y se garantiza que permanecerá igual hasta que ya no está en uso. Actualmente tengo:¿Cómo devuelve std :: string :: c_str() un c-string que no causa una pérdida de memoria o un contenido indefinido de c-string?

const char* string::c_str() 
{ 
    char c[_size+1]; 
    strncpy(c,_data,_size); 
    c[_size]='\0'; 
    return c; 
} 

pero los contenidos se anulan poco después de su llamada. Si realizo la asignación dinámica, tendré una fuga de memoria o solo una cadena de caracteres puede existir de una cadena dada en cualquier momento. ¿Cómo puedo evitar esto?

+1

"* o solo una cadena de caracteres puede existir de una cadena dada en cualquier momento *" Así es como funciona 'std :: string' - ¿cuál es el problema? – ildjarn

+0

Si 'strncpy()' es la respuesta, probablemente estés [haciendo la pregunta incorrecta] (http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not- safer-strcpy.html). –

+0

No me di cuenta que tenía que existir solo hasta que se cambiara. Ahora funciona en O (1) vez. –

Respuesta

7

Pero la cadena apuntada por c_str solo está bien definida hasta que se modifique (o destruya) el std::string.

Una forma de lograr esto podría ser simplemente devolver un puntero a su búfer interno (suponiendo que tiene terminación nula). Tenga en cuenta que una norma c_str debe funcionar en O (1) tiempo; así que no está permitido copiar.

+1

Bueno saberlo. Eso es casi como forzar una cierta implementación de la clase 'std :: string', concretamente como una matriz de caracteres. – alfC

4

De http://www.cplusplus.com/reference/string/string/c_str/:

Los puntos de matriz devuelta a una ubicación interna con el espacio requerido de almacenamiento para esta secuencia de caracteres más su terminación null-carácter, pero los valores en esta matriz no debe ser modificado en el programa y solo se garantiza que permanezcan sin cambios hasta que la siguiente llamada a una función de miembro no constante del objeto de cadena.

0

No se garantiza que el almacenamiento intermedio devuelto por c_str() permanezca igual o incluso válido hasta que ya no se use.

Solo se garantiza que permanecerá válido hasta que std :: string cambie de alguna manera.

La implementación es sencilla: simplemente mantenga la representación interna de la cadena con terminación nula en todo momento, y devuelva un puntero a la representación interna desde c_str().

Cuestiones relacionadas