дублировать структуру typedef через указатель - PullRequest
0 голосов
/ 03 ноября 2011

У меня определены следующие typedef и * ButtonSettingPtr в качестве указателя:

 typedef struct
    {
      void     *next;
      char**   buttonsetting;
      char*    currentsetting;
      uint16_t presetid;
      uint16_t currentcounter;
      uint16_t maxsize;
      uint16_t buttonid;
    } ButtonSetting;

typedef ButtonSetting *ButtonSettingPtr;


class Options {
 private:
  ButtonSettingPtr settings;
  ButtonSettingPtr preset1;
public:
Options();
void newSetting(char** _setting, uint16_t _maxsize, uint16_t _buttonid);
// some other stuff defined here
}

С помощью функции newSetting () я добавляю несколько новых записей в мой экземпляр typedef!Теперь я хотел бы сохранить все эти настройки (this-> settings) в другом указателе (this-> preset1) через memcpy, чтобы позже вызвать их снова через другую функцию, так как я использую this-> settings в нескольких другихфункции (getCurrentSetting), которые работают довольно хорошо и т. д.

char *Options::getCurrentSetting(uint16_t _buttonid) {
  ButtonSettingPtr setting = (ButtonSettingPtr)this->settings;
  while (setting != NULL)
  {
    if (setting->buttonid == _buttonid) {
      char * tmpsetting = 
        setting->buttonsetting[setting->currentcounter];
      return tmpsetting;

    }
    setting = (ButtonSettingPtr)setting->next;
  }
  return NULL;
}

Вот проблема:

void Options::savePreset() {
  memcpy(&this->preset1,&this->settings,sizeof(&this->settings));
}
void Options::loadPreset() {
  memcpy(&this->settings,&this->preset1,sizeof(&this->preset1));
}

Кажется, что мой указатель preset1 всегда точно такой же, как this-> даже настройкихотя я меняю настройки между ними.Я понимаю, что со знаком & он буквально копирует адрес этого указателя, поэтому неудивительно, что оба они всегда будут одинаковыми.Но я хотел бы скопировать все байты и указать их на preset1, чтобы я мог позже вспомнить все настройки.

Итак, без знака & мой код просто зависает:

void Options::savePreset() {
  memcpy(this->preset1,this->settings,sizeof(this->settings));
}
void Options::loadPreset() {
  memcpy(this->settings,this->preset1,sizeof(this->preset1));
}

Должен ли я указывать malloc указатель this-> preset1, прежде чем я запомню все к нему?Весь код скомпилирован с использованием avr-libc для чипа atmega.

Заранее благодарен за любой полезный совет!

ps: Мое понимание C ++ было несомненно лучше, когда я был моложе!

Ответы [ 3 ]

0 голосов
/ 03 ноября 2011

Да, вам нужно malloc preset1 (не нужно разыменовывать его с помощью this-> внутри функции-члена. Если вы хотите прояснить, что это член класса, назовите его m_preset1 или mPreset1, как вам нравится).

Итак, в вашем конструкторе установите preset1 в NULL.Тогда в вашей функции-члене вы можете:

void Options::savePreset() {
    if (preset1 == NULL) {
        preset1 = (ButtonSettingPtr)malloc(sizeof (ButtonSetting));
    }
    memcpy(preset1, settings, sizeof(ButtonSetting));
}

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

class Options {
private:
    ButtonSetting settings;
    ButtonSetting preset1;
public:
    Options();
    void newSetting(char** _setting, uint16_t _maxsize, uint16_t _buttonid);
    // some other stuff defined here
}

void Options::savePreset() {
    memcpy(&preset1, &settings, sizeof(ButtonSetting));
}

Обратите внимание, что sizeof (this-> settings) всегда будет 4 или 8 (в зависимости от 32или 64-битный процессор), потому что вы запрашиваете размер указателя, а не размер структуры.

0 голосов
/ 03 ноября 2011
sizeof(&this->settings)

вернет размер указателя, потому что он фактически является указателем.

sizeof(this->settings)

вернет размер указателя, потому что это указатель.

sizeof(*this->settings)

вернет размер анонимной структуры, на которую указывают настройки.

А что касается вопроса о необходимости malloc места для

 this->preset1

зависит от вашего кода. Но это наверняка должно указывать на действительную память!

0 голосов
/ 03 ноября 2011

Похоже, вы создаете доморощенный односвязный список.Если вы замените это на std::vector, вы обнаружите, что копировать одно в другое так же просто, как preset1 = settings; (вам не нужно ставить this-> перед всем, если вы просто не предпочитаете этот стиль).*

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...