Странное поведение с массивами char/uint8

Итак, я пытаюсь прочитать 8-байтовую строку символов с устройства I2C и распечатать ее на последовательной консоли. Этот необработанный массив из 8 символов не завершается, когда он поступает с устройства, поэтому я почти уверен, что мне придется завершить его вручную. К сожалению, когда я распечатываю полученную строку, последовательный монитор просто заполняется разрывами строк. Может ли кто-нибудь взглянуть на этот код и сказать мне, где я ошибся?

uint8_t* HT_Controller::readMultiple(uint8_t reg, uint8_t num)
{
    Wire.beginTransmission(i2cAddr);
    Wire.write(reg);
    Wire.endTransmission();

    Wire.requestFrom(i2cAddr, num);
    uint8_t* data = new uint8_t[num];

    for(int i = 0; i < num; i++)
    {
        data[i] = Wire.read();
    }

    return data;
}

char* HT_Controller::getManufacturer()
{
    uint8_t* data = readMultiple(REGISTER_MFR, NUM_MFR_BYTES); //Читаем байты из контроллера
    char* dataTerminated = new char[NUM_MFR_BYTES + 1]; //Наш новый массив, в конце которого будет нулевой символ
    memcpy(data, dataTerminated, NUM_MFR_BYTES); //Копируем байты в новый массив
    delete(data); //Мы закончили с исходным массивом, удаляем его из кучи
    dataTerminated[NUM_MFR_BYTES] = 0; //Добавьте этот нулевой символ. Примечание: нам не нужно добавлять «+1» к индексу, поскольку массивы начинаются с 0, а не с 1.

    return dataTerminated;
}

А вот как это используется в основном скетче:

void loop()
{
    char* data = mc1->getManufacturer();
    Serial.println(data);
    delete(data);
    delay(500);
}

, 👍0

Обсуждение

Подсказка №1: проверьте порядок параметров memcpy(), http://www.cplusplus.com/reference/cstring/memcpy/. И попробуйте написать код без использования кучи (создать/удалить)., @Mikael Patel

@MikaelPatel, как мне избежать использования кучи, учитывая, что это для библиотеки?, @You'reAGitForNotUsingGit

Совет №2: используйте стек и передавайте возвращаемые значения по ссылке. например, «char dataTerminate[NUM_MFR_BYTES + 1]; readMultiple(REGISTER_MFR, NUM_MFR_BYTES, dataTerminate);», @Mikael Patel

@MikaelPatel подожди, но разве возврат указателя на локальный массив не является нет-нет?, @You'reAGitForNotUsingGit

О, кажется, я понимаю, что ты имеешь в виду сейчас, @You'reAGitForNotUsingGit

@MikaelPatel хм, так что это все хорошо для readMultiple(), но чтобы применить это к getManufacturer(), пользователю нужно знать, что массив, который он передает для вывода, должен иметь длину 9 символов. ..., @You'reAGitForNotUsingGit


1 ответ


Лучший ответ:

1

Ваш memcpy перевернут.

SYNOPSIS
   #include <string.h>

   void *memcpy(void *dest, const void *src, size_t n);

Итак, строка:

memcpy(data, dataTerminated, NUM_MFR_BYTES); //Копируем байты в новый массив

должно быть:

memcpy(dataTerminated, data, NUM_MFR_BYTES); //Копируем байты в новый массив
,