Данные между указателями - PullRequest
1 голос
/ 06 мая 2011

Если выполняется следующее, будут ли скопированы фактические данные в указателе или сам указатель?

void nav_runGpsSystem(GPSLocation *dest)
{   
    GPSLocation *destination = malloc(sizeof(GPSLocation));
    destination = dest;

Где GPSLocation является следующим

typedef struct
{
    double latitude;
    double longitude;
}
GPSLocation;

Проблема в том, что GPSLocation, который создается, указатель, создается за пределами подсистемы, которая его использует, но он все еще на той же плате (pandaboard под управлением Ubuntu Netbook Edition) Я не хочу, чтобы данные были потеряны, так как указатели как-то повредились, поэтому я хочу скопировать данные, на которые указывал первый указатель, чтобы система, создавшая их, могла освободить указатель, когда они захотят.

EDIT

После прочтения ответов ясно, что я должен разыскивать, используя *destination = *dest

Так что если я захочу передать данные в потоки

как так

void *startgpswatchdog(void *ptr)
{
    GPSLocation *destination;
    destination = (GPSLocation *) ptr;

Если у меня есть данные, скопированные в мою систему сейчас, есть ли необходимость снова копировать данные в pthread или достаточно передать только указатель, так как он уже расположен неправильно, и потоки разделяют то же пространство памяти?

Ответы [ 5 ]

1 голос
/ 06 мая 2011

Если вы разделите определение и инициализацию в 2 строки, может быть легче "увидеть", что это не работает

void nav_runGpsSystem(GPSLocation *dest) {
    GPSLocation *destination;
    destination = malloc(sizeof(GPSLocation));
    destination = dest; /* overwrite malloc return value and leak memory */

Ваше редактирование в порядке (за исключением избыточного приведения).

1 голос
/ 06 мая 2011

Вы выделяете пункт назначения для нового блока памяти, но затем указываете на этот блок (утечка памяти - вы не можете вернуть эту запись) и указываете на существующий объект dest. dest и destination - два указателя, указывающие на один и тот же объект.
Если вы хотите скопировать объект, вам нужно разыменовать: * destination = * dest;
Но тогда вам нужно каким-то образом следить за назначением ptr, чтобы впоследствии вы могли освободить эту выделенную память - из вашего примера непонятно, как вы собираетесь это сделать. Вы тогда подразумеваете, что собираетесь использовать несколько потоков, обращающихся к объекту? - осторожно, здесь вам нужно будет защитить объект мьютексом или критической секцией, чтобы избежать параллельного доступа.

1 голос
/ 06 мая 2011

Вы копируете сам указатель.

destination = dest;

Так что теперь пункт назначения будет указывать на то, на что указывает пункт.

1 голос
/ 06 мая 2011

Строка destination = dest; не копирует данные, а вместо этого destination указывает на те же данные, что и dest.В памяти по-прежнему остается только одна копия данных, просто сейчас на нее указывают dest и destination.

Вам нужно будет разыменовать обауказатели:

*destination = *dest;

Это фактически говорит: «возьмите данные, на которые указывает dest, и скопируйте их в местоположение, на которое ссылается destination».

РЕДАКТИРОВАТЬ: В ответ на редактирование вопроса: все ваши потоки совершенно нормально ссылаются на одни и те же данные в памяти, поэтому, если у вас нет особой причины сделать копию для каждого из ваших потоков, то у вас все в порядке.Вы должны знать о проблемах синхронизации - что произойдет, если два потока попытаются изменить общие данные одновременно?Если это проблема, вы должны рассмотреть такие вещи, как мьютексы , семафоры и т. Д.

1 голос
/ 06 мая 2011

Он не будет работать должным образом, он просто назначит указатель, и вы потеряете malloc редактируемую память.

Вам нужно разыменовать указатели:

void nav_runGpsSystem(GPSLocation *dest)
{   
    GPSLocation *destination = malloc(sizeof(GPSLocation));
    *destination = *dest;
}

этого должно быть достаточно.

РЕДАКТИРОВАТЬ
Это нормально, так как поток разделяет то же пространство памяти.Убедитесь, что каждый поток имеет свою копию оригинальной структуры.

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