2012-03-22 21 views
5

Ho sviluppato una piccola funzione di supporto per una classe di test dell'unità, che prende il mio vector<unsigned char> e lo converte in un const char *. Ho scritto questo così posso passarlo alla macro ASSERT_STREQ di gtest per semplici confronti. Eccolo:Funzione C++ restituendo 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; 
} 

Ed ecco un esempio di esso che è chiamato:

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

Presumo che questo è che perde tuttavia come sto chiamando malloc, ma senza chiamare delete a valle della strada?

Esiste un modo più elegante per eseguire questa operazione, che non comporta la creazione di una variabile const char * separata per ogni volta che si chiama ASSERT_STREQ all'interno di un metodo di prova?

Grazie mille in anticipo per tutte le risposte.

Chris

+1

Usa 'free()' 'dopo malloc()', 'non delete'. – hmjd

+0

+1 per una domanda interessante. Non ho davvero una risposta, però. Questo sembra un attacco gigantesco solo per i test unitari. Hai preso in considerazione la creazione di un 'ASSERT_VECEQ'? Inoltre, forse non dovresti preoccuparti troppo delle perdite di memoria nei test unitari. –

+0

Ok, grazie per avermelo fatto notare. –

risposta

11

Return un std::string invece di un char* (malloc(), o new, non desiderati):

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

ed impiego:

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

Questo sembra essere l'approccio del buon senso :) Grazie! –

1

Si dovrebbe solo utilizzare string container - no è necessario preoccuparsi di perdite di memoria.

BTW - Poiché si utilizza C++, attenersi semplicemente a new e delete.

0

Stavo per raccomandare di usare anche std :: string, ma mi stavo chiedendo, perché non confrontare semplicemente il contenuto del vettore? È possibile accedere ai dati grezzi attraverso &source[0], in modo che si possa fare:

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

Provato questo, ma il test non è riuscito - 'ASSERT_STREQ (" de ", (const char *) & ret [0]);' - penso che sia perché non c'è alcun byte 0 alla fine del vettore. –

+0

@MrChris: Sì, non avevo pensato a quello – MikMik

2

sovraccarico operator==, allora si può solo utilizzare ASSERT_EQ:

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

Usa come:

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

You' È necessario sovraccaricare anche operator<<(std::ostream& ..., poiché GoogleTest lo utilizza per convertire gli argomenti nell'asserzione in messaggi di errore se l'asserzione fallisce.

edit:

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

mi piace - sembra molto elegante. Ma avrò bisogno di alcuni compiti su come implementare correttamente il sovraccarico! (Ancora un po 'di n00b in questa roba). Grazie per il suggerimento. –

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