Скопируйте временную структуру, используя malloc и пустой указатель - PullRequest
0 голосов
/ 22 ноября 2011

У меня есть следующая функция, которая вызывается как запуск модуля для программы на встроенных часах AVR. Я хочу получить значение из объекта clock, который вернет структуру date_time и скопировать его в пространство, которое я выделяю из кучи.

void time_set_mode_start(Display *display, volatile Controls *controls,
                         volatile TimeKeeper *clock, void *data) {

    DEBUG_LED_PORT |= _BV(DEBUG_LED);
    data = malloc(sizeof(date_time));
}

Каков наилучший способ получить данные, возвращаемые функцией clock-> getTime (), в указатель данных?

Ответы [ 2 ]

4 голосов
/ 22 ноября 2011

Одним из способов является использование memcpy. В частности, вы, вероятно, хотели бы memcpy(data, clock->getTime(), sizeof(date_time)).

Другой способ & mdash; наверное, лучше, теперь, когда я думаю об этом & mdash; использовать обычное задание:

*((date_time*)data) = *(clock->getTime());

Это обрабатывает data как date_time * и присваивает значение объекту date_time, на который он указывает.

(Примечание: в обоих приведенных выше фрагментах кода я предполагаю, что clock->getTime() возвращает date_time *. Это правильно?)

Кстати, я должен отметить, что data = malloc(sizeof(date_time)); полностью заменит исходный void * data, который был передан. Ваш абонент никогда не увидит ячейку памяти, на которую указывает data, поскольку указатель передается по значению.

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

Либо вызывающему коду необходимо выделить пространство для значения и передать его в функцию, показанную как параметр data, либо прототип функции должен иметь void **data, чтобы функция могла передать значение обратно. В существующем состоянии ваш код перезаписывает локальную копию data новым выделенным значением, что приводит к утечке памяти при возврате.

Предполагается, что прототип date_time TimeKeeper::getTime():

void time_set_mode_start(Display *display, volatile Controls *controls,
                         volatile TimeKeeper *clock, void **pdata)
{
    DEBUG_LED_PORT |= _BV(DEBUG_LED);
    *data = malloc(sizeof(date_time));
    *(date_time *)(*data) = clock->getTime();
}

Если прототипом является date_time *TimeKeeper::getTime(), тогда присваивание:

    *(date_time *)(*data) = *clock->getTime();

Если это что-то еще, вы должны сообщить нам.

...