Почему я получаю ошибку сегментации после назначения указателя? - PullRequest
0 голосов
/ 05 марта 2012

Я получил ошибку сегментации, когда вызвал функцию сразу после назначения указателя.

typedef struct
{
   DMINT field1;
   DMINT field2;
   DMINT field3;
} MSG1;

typedef struct
{
....
} MSG;

/* MSG is size of 1040 byte, bigger than MSG1 in size */

int main()
{
    MSG     Msg;
    MSG1   *pMsg1;
    int     mid;
    pthread_t  tid;
    ...

    Recv_msg( mid, &Msg);   /* this function does a memcpy to &Msg */
    pMsg1 = (MSG1 *)&Msg;

    //ret = pthread_join(pMsg1->..... );    /* Got Segmentation fault here by GDB*/
    /* even the first argument has nothing to do with pMsg1, SEGV is still received */
     ret = pthread_creat(&tid, NULL, thread_function, NULL); /* Got Segmentation fault here by GDB*/

Работает нормально, если удалить pMsg1 = (MSG1 *)&Msg.Это потому, что два указателя имеют разные размеры?

Ответы [ 3 ]

2 голосов
/ 05 марта 2012

Вы можете безопасно преобразовать один указатель структуры в другой только в том случае, если одна структура лежит в начале другой (независимо от размера, см. C-стандарт.):

typedef struct {
  int a;
} S1;
typedef struct {
  S1 s1; // <- s1 it the FIRST structure field
  int b;
} S2;
S2 s2;
S1 *s1;
s1= (S1*)&s2; // <- safe

В противном случае вы можете столкнуться с проблемами выравнивания и неопределенного поведения.

0 голосов
/ 05 марта 2012

Если структуры не идентичны, не копируйте, назначив

 pMsg1 = (MSG1 *)&Msg;

Копировать структуры отдельных элементов. Тогда это решает вашу проблему.

0 голосов
/ 05 марта 2012

MSG1 и MSG - это разные типы.

pMsg1 указывает на Msg, который имеет тип MSG, но имеет тип MSG1*.

При попытке доступа к полям из MSG1, в области памяти, где лежит MSG, вы получаете неопределенное поведение.

...