printf вызывает ошибку сегментации? - PullRequest
0 голосов
/ 06 марта 2020

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

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 


void *thread (void *vargp) {
   int arg = *((int*)vargp);
   return &arg;
}   

int main () {
   pthread_t tid;
   int thread_arg = 0x7ffdbc32fa34;
   int *ret_value;
   pthread_create(&tid, NULL, thread, &thread_arg);
   pthread_join(tid, (void **)(&ret_value));
   printf("hello\n");
   printf("%X\n", *ret_value);
   return 0; 
}

Это дает следующий вывод:

hello
Segmentation fault (core dumped)

Это потому, что я возвращаю адрес локальной переменной, которая уничтожается при возврате потока? Я так не думаю, потому что переход на следующий код также вызывает ошибку сегментации!

void *thread (void *vargp) {
    int * arg = malloc(sizeof(int));
    *arg = *((int*)vargp);
    return &arg;
}   

1 Ответ

2 голосов
/ 06 марта 2020

Это потому, что я возвращаю адрес локальной переменной, которая уничтожается при возврате потока?

Да, это так.

Я так не думаю, потому что переход на следующий код также вызывает ошибку сегментации!

Этот код также возвращает адрес локальной переменной (return &arg; ). Вместо этого вам следует возвращать значение указателя, которое вернул malloc() (return arg;):

void *thread (void *vargp)
{
    int * arg = malloc(sizeof(int));
    *arg = *((int*)vargp);
    return arg;
} 

Также не следует приводить адрес ret_value к типу void ** в main() - переменная имеет тип int *, а не void *, поэтому она не должна записываться через указатель void ** (хотя на практике это обычно работает). Вместо этого вы должны использовать переменную void * для хранения возвращаемого значения, а затем либо привести это значение к int *, либо присвоить его переменной типа int *:

void *ret_value;
pthread_create(&tid, NULL, thread, &thread_arg);
pthread_join(tid, &ret_value);
printf("%X\n", *(int *)ret_value);
...