Преобразование std :: vector <char>в char * приводит к появлению дефектных символов - PullRequest
1 голос
/ 24 июня 2019

В моем коде есть функция с именем buildPacket, которая принимает некоторые параметры, преобразует их в char*, добавляет их вместе, используя std::vector<char>, и в конце возвращает результат как char*.Проблема в том, что после того, как я преобразовал вектор в char*, все символы стали странными.

Я попытался использовать другие способы преобразования вектора в char*, например, используя reinterpret_cast<char*>.Когда я печатаю содержимое вектора изнутри функции, я получаю ожидаемый результат, поэтому проблема в преобразовании.

Код функции:

char* buildPacket (int code, std::string data)
{
    char* codeBytes = CAST_TO_BYTES(code);
    std::vector<char> packetBytes(codeBytes, codeBytes + sizeof(char));
    size_t dataLength = data.size() + 1;
    char* dataLengthBytes = CAST_TO_BYTES(dataLength);
    packetBytes.insert(packetBytes.end(), dataLengthBytes, dataLengthBytes + sizeof(int));
    const char* dataBytes = data.c_str();
    packetBytes.insert(packetBytes.end(), dataBytes, dataBytes + dataLength);

    return &packetBytes[0];
}

Макрос CAST_TO_BYTES:

#define CAST_TO_BYTES(OBJ) static_cast<char*>(static_cast<void*>(&OBJ));

Цель функции - взять входные данные и создать из них пакет для последующей отправки через сокет. Формат пакета состоит из 1-байтового длинного кода и 4-байтового кода.длинная длина данных и данные с переменной длиной.

Введенные мной данные code = 101 и data = "{\"password\":\"123456\",\"username\":\"test\"}"

Это результат, который я получаю при печати символов: ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌

РЕДАКТИРОВАТЬ: Спасибо за всю помощь, я возвратил vector<char> в конце, как предложено, и использовал другой подход при преобразовании значений в char*.

Ответы [ 2 ]

5 голосов
/ 24 июня 2019

Вы возвращаете указатель на что-то внутри локальной переменной.Вы должны изменить свой код, чтобы ваш vector<char> был активным вне вашей функции buildPacket (например, возвращая его вместо char*).

2 голосов
/ 24 июня 2019

Вы можете попробовать это решение. Я думаю, что использование STL делает более понятным, чего вы пытаетесь достичь. В вашем коде также была неопределенная ссылка, которая могла привести к непредсказуемым сбоям.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

// Better return std::vector<char>
char* buildPacket(int code, const std::string& data)
{
    auto result = data;
    result.append(1, static_cast<char>(code));

    char* ret = new char[data.size() + 2];
    ret[data.size() + 1] = '\0';
    std::copy(result.begin(), result.end(), ret);

    return ret;
}

std::vector<char> buildPacketStl(int code, const std::string& data)
{
    std::vector<char> ret;
    std::copy(data.begin(), data.end(), std::back_inserter(ret));
    ret.push_back(static_cast<char>(code));
    return ret;
}

int main() {
    std::cout << buildPacket(65, "test") << std::endl;; // 65 -> A
    auto stl= buildPacketStl(65, "test"); // 65 -> A
    std::copy(stl.begin(), stl.end(), std::ostream_iterator<char>(std::cout, ""));
    std::cout << std::endl;

}
...