c структуры и распределение указателей - PullRequest
0 голосов
/ 30 октября 2018

Я выполняю задание, где мне нужно обработать несколько изображений с pthreads C.

У меня есть следующие структуры:

typedef struct {
    int type;
    int width;
    int height;
    int max_value;
    int *input;
}image;

и

typedef struct {
    int id; // thread id
    image *in; //input image
}ptf_arguments;

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

void resize(image *in, image * out) {
    int i;
    pthread_t tid[num_threads];
    ptf_arguments *arguments[num_threads];
    arguments[0]->in->input = (int *)malloc(in->width * in->height * sizeof(int));
    arguments[0]->in = in; // HERE

    printf("First thread should have id = %d. In image of (%d)\n", arguments[0]->id, arguments[0]->in->width); //here
    for(i = 0 ; i < num_threads; i++) {
        pthread_create(&(tid[i]), NULL, resize_thread_function, &(arguments[i]));
    }
}

1) Я не очень хорошо понимаю структуры, и мне нужен кто-то, кто объяснит мне, как я могу передать входящие / исходящие изображения в мою структуру ptf_arguments, чтобы я мог передать ее в функцию pthreads.

2) Нужно ли выделять память для структуры изображения?

3) Нужно ли выделять память для массива int внутри структуры изображения структуры ptf_arguments?

Спасибо

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Структура - это, по сути, объект, для которого нельзя изменить части.
Это в основном похоже на переменную Javascript. Вы получаете доступ к его частям с точкой varname.subpartname, если переменная простая, со стрелкой varname->subpart, если это указатель.

Структуры являются типами переменных. Вам не нужно выделять им память (кроме случаев, когда используются указатели ...)

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

void resize(image *in, image * out) {
    pthread_t tid[num_threads];
    ptf_arguments *arguments[num_threads];
//    arguments[0]->in->input = malloc(in->width * in->height * sizeof(int));
//The preceding line is useless (and also using an uninitialized item). You already have a complete pointer.
    arguments[0]->in = in; // HERE

    printf("First thread should have id = %d. In image of (%d)\n", arguments[0]->id, arguments[0]->in->width); //here
    for(int i = 0 ; i < num_threads; i++) {//Since you only use int i here, you can declare it in the for condition
        pthread_create(&(tid[i]), NULL, resize_thread_function, &(arguments[i]));
    }
}
0 голосов
/ 30 октября 2018

1) Я не очень хорошо понимаю структуры, и мне нужен кто-то, кто объяснит мне, как я могу передать входящие / исходящие изображения в мою структуру ptf_arguments, чтобы я мог передать ее в функцию pthreads.

Если вам нужна 1 структура на поток, передайте ее по адресу pthread_create по адресу, используя параметр arg. Как вы уже пытались: &(arguments[i]). Вы, вероятно, хотели просто сделать arguments[i], так как это указатель. На самом деле вы передаете не данные, выделенные адресом, а адрес локального указателя, что неверно и неверно.

ВАЖНО: Никогда не передавайте потоку указатель на локальную переменную! Переменная должна быть распределена либо со статической продолжительностью хранения, либо с помощью динамического выделения.

Если вы «не очень хорошо понимаете структуры», вам, вероятно, следует изучить их и попрактиковаться в их использовании, прежде чем переходить к более сложным темам, таким как многопоточность. В общем, вы не можете программировать методом проб и ошибок, вам нужно знать, что делает каждая напечатанная строка. Там нет "рискнуть".

2) Нужно ли выделять память для структуры изображения?

Да. И это еще одна причина, почему ваш код не работает. ptf_arguments *arguments[num_threads]; - это просто массив указателей, память для фактических данных не выделяется.

3) Нужно ли выделять память для массива int внутри структуры изображения структуры ptf_arguments?

Да.

Также не забудьте free всю память, когда закончите использовать его. Функция «resize», вероятно, не должна выделять ресурсы, если она не освобождает ранее использованные ресурсы.

0 голосов
/ 30 октября 2018

Когда я читаю код, я вижу

ptf_arguments *arguments[num_threads];
arguments[0]->in->undefined behavior

Вам нужно указать in на действительную структуру image перед разыменованием. Самый простой способ - переместить помеченную вами строку //HERE выше предыдущей строки.

Да, вам также нужно выделить массив int и указать элемент input структуры image в этой памяти. Само собой разумеется, вам нужно будет выполнить эту инициализацию и распределение для каждого ptf_arguments объекта, а не только для первого.

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

...