Функция C ++, возвращающая const char * - PullRequest
5 голосов
/ 22 марта 2012

Я разработал небольшую вспомогательную функцию для класса модульного тестирования, которая берет мой vector<unsigned char> и преобразует его обратно в const char *. Я написал это, чтобы я мог передать его в макрос gtest ASSERT_STREQ для простых сравнений. Вот оно:

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

А вот пример того, как его называют:

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

Я полагаю, что это утечка, поскольку я звоню malloc, но без звонка delete дальше по дороге?

Существует ли более элегантный способ сделать это, который не предусматривает создание отдельной переменной const char * для каждого вызова в методе теста ASSERT_STREQ?

Большое спасибо заранее за все ответы.

Chris

Ответы [ 5 ]

11 голосов
/ 22 марта 2012

Верните std::string вместо char* (malloc() или new, не требуется):

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

и используйте:

ASSERT_STREQ("de", convertVecToChar(somevector).c_str());  
2 голосов
/ 22 марта 2012

Перегрузка operator==, тогда вы можете просто использовать ASSERT_EQ:

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

Использовать как:

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

Вам также потребуется перегрузить operator<<(std::ostream& ..., так как GoogleTest используетчтобы преобразовать аргументы утверждения в сообщения об ошибках, если утверждение не удалось.

edit:

std::ostream& operator<<(std::ostream& os, const std::vector<char>& chars)
{
    return os << std::string(chars.begin(), chars.end());
}
1 голос
/ 25 марта 2012
source.push_back(0);
ASSERT_STREQ("de", (char*)&source[0]);
source.pop_back();
1 голос
/ 22 марта 2012

Вы должны просто использовать строка контейнер - не нужно беспокоиться об утечках памяти.

Кстати: поскольку вы используете C ++ - просто придерживайтесь new и delete.

0 голосов
/ 22 марта 2012

Я тоже собирался порекомендовать использовать std :: string, но мне было интересно, почему бы просто не сравнить содержимое вектора? Вы можете получить доступ к необработанным данным через &source[0], так что вы можете сделать:

ASSERT_STREQ("de", (char*)&source[0]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...