2013-06-29 3 views
2

Я застрял в простом указателе/​​литье проблемы:C, отбрасывая массив структур, передаваемых через пустой указатель

Я пытаюсь передать в качестве аргумента функции PTHREAD в pthread_create массив из 2 структур. Вот код:

struct sockaddr_in addr_left, addr_right; 
struct sockaddr_in* addr_vec [2] = {&addr_left, &addr_right}; 
pthread_create (&thread_forward, NULL, thread_func_forward, (struct sockaddr**)addr_vec); 

Внутри thread_func_forward:

void * thread_func_forward (void * argv) { 
    struct sockaddr_in* addr_left = ((struct sockaddr_in*)argv + 0); 
    struct sockaddr_in* addr_right = ((struct sockaddr_in*)argv + 1); 
} 

По какой-то причине он не работает должным образом, программа может выполнять последние строки без ошибки сегментации, но когда я получить доступ к членам структур, они полностью изменены

+1

Я полагаю, что 'addr_left',' addr_right' и массив являются локальными переменными функции, которые находятся в стеке. Когда вы возвращаете форму этой функции, эти переменные стека уходят/мусорятся. –

+1

Пробовал ли вы один раз с обычным вызовом функции вместо потоков? Это хорошо работает? – VoidPointer

ответ

3

Вы не возвращаете свой аргумент потока в нужный тип. Ваш код передает аргумент потока в struct sockaddr_in *, но это неправильный тип. addr_vec - массив указателей, и поэтому addr_vec будет распадаться на указатель на указатель.

Поскольку вы передаете указатель на указатель, вы должны использовать его как таковое в своей функции потока. Затем вам нужно разыменовать его, чтобы получить указатель, который вы хотите.

struct sockaddr_in* addr_left = *((struct sockaddr_in**)argv + 0); 
    struct sockaddr_in* addr_right = *((struct sockaddr_in**)argv + 1); 

Тот факт, что те, указатели на локальные автоматические переменные из функции, создающей нити могут или не могут быть проблемой. Это зависит от того, будет ли эта функция ждать завершения потоков до того, как эти переменные выйдут из области видимости.

+0

Имеет смысл, теперь он работает. Огромное спасибо. –

+0

Добро пожаловать. – jxh

1

Ваш addr_vec живет в автоматическом хранилище (то есть в стеке), но нет никаких указаний на то, что вы предприняли какие-либо шаги для обеспечения того, чтобы продолжительность жизни переменной длилась как минимум до тех пор, пока Точка вы обращаетесь к ним в потоке.

Короче говоря, вам необходимо либо динамически распределить перед созданием потока, либо затем отпустить его в потоке, либо использовать примитивы синхронизации, чтобы предотвратить создание функции, из которой вы создаете поток, прежде чем вы сделаете копию в самом потоке ,