2012-03-22 33 views
5

He desarrollado una pequeña función de ayuda para una clase de prueba de unidad, que toma mi vector<unsigned char> y la convierte de nuevo a const char *. Escribí esto para poder pasarlo a la macro ASSERT_STREQ de gtest para hacer comparaciones simples. Aquí está:C++ función que devuelve const char *

const char * convertVecToChar(std::vector<unsigned char>& source) 
{ 
    std::vector<unsigned char>::size_type size = source.size(); 
    char* data = (char*)malloc(sizeof(char) * (size + 1)); 
    memcpy(data, &source[0], size); 
    data[size] = 0; 
    return data; 
} 

Y aquí está un ejemplo de lo que se llama:

ASSERT_STREQ("de", convertVecToChar(somevector)); 

Supongo que esto es permeable sin embargo, como estoy llamando malloc, pero sin llamar delete más por el camino?

¿Hay una forma más elegante de hacerlo, que no implica la creación de una variable const char * por cada vez que llamo a ASSERT_STREQ dentro de un método de prueba?

Muchas gracias de antemano por todas las respuestas.

Chris

+1

Use 'libre()' 'después de malloc()', 'no delete'. – hmjd

+0

+1 para una pregunta interesante. Aunque realmente no tengo una respuesta. Esto parece un truco gigante solo para pruebas unitarias. ¿Consideraste crear un 'ASSERT_VECEQ'? Además, tal vez no debería preocuparse demasiado por las pérdidas de memoria en las pruebas unitarias. –

+0

Bien, gracias por avisarme. –

Respuesta

11

devolver un std::string en lugar de un char* (malloc() o new, no requerido):

std::string convertVecToChar(std::vector<unsigned char>& source) 
{ 
    return std::string(source.begin(), source.end()); 
} 

y uso:

ASSERT_STREQ("de", convertVecToChar(somevector).c_str()); 
+1

Este parece ser el enfoque de sentido común :) ¡Gracias! –

1

Usted sólo debe utilizar string contenedor - sin necesita preocuparse por las pérdidas de memoria.

BTW - Como está utilizando C++, simplemente se adhieren a new y delete.

0

Iba a recomendar el uso de std :: string también, pero me preguntaba, ¿por qué no comparar el contenido del vector? Se puede acceder a los datos en bruto a través &source[0], por lo que podría hacer:

ASSERT_STREQ("de", (char*)&source[0]); 
+1

Intenté esto, pero falló la prueba: 'ASSERT_STREQ (" de ", (const char *) y ret [0]);' - creo que es porque no hay un byte 0 al final del vector. –

+0

@MrChris: Sí, no había pensado en eso – MikMik

2

sobrecarga operator==, a continuación, puedes utilizar ASSERT_EQ:

bool operator==(const char* nullTerminatedChars, 
       const std::vector<char>& vecChars) 
{ 
    return std::string(nullTerminatedChars) == 
      std::string(vecChars.begin(), vecChars.end()); 
} 

Utilizar como:

std::vector<char> chars; 
ASSERT_EQ("de", chars); 

usted' Necesitaré también sobrecargar operator<<(std::ostream& ..., ya que GoogleTest lo usa para convertir argumentos a la afirmación en mensajes de error si la afirmación falla.

edición:

std::ostream& operator<<(std::ostream& os, const std::vector<char>& chars) 
{ 
    return os << std::string(chars.begin(), chars.end()); 
} 
+0

Me gusta esto, se ve muy elegante. ¡Pero va a necesitar algunos deberes sobre cómo implementar la sobrecarga correctamente! (Todavía un poco de n00b en esto). Gracias por la sugerencia. –

1
source.push_back(0); 
ASSERT_STREQ("de", (char*)&source[0]); 
source.pop_back(); 
Cuestiones relacionadas