Как освободить () указатель буфера во вторичном потоке, если указатель был создан с помощью mallo c () в основном потоке? - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь реализовать решение, основанное частично на обсуждениях ниже. В основном, я хочу malloc() в основном потоке и free() в дополнительном потоке. Связанные обсуждения касаются Lab Windows, но я думаю, что мой вопрос больше ориентирован на C программистов в целом.

Lab Windows: реализация потоковобезопасных очередей, которые могут обрабатывать строковые элементы

Как использовать потокобезопасную очередь для хранения строк

Я создаю указатель на char в главном потоке и выделяю память, используя malloc(). Я копирую некоторые данные в хранилище и назначаю указатель на элемент массива (CmtWriteTSQData ожидает массив). Этот массив передается в потокобезопасную очередь.

Во вторичном потоке потокобезопасная очередь читается. Данные присваиваются новому массиву.

Как освободить память, выделенную во вторичном потоке, поскольку переменная-указатель больше не находится в области видимости?

Может Я просто вызываю free() для элемента массива? Или мне нужно создать другой указатель на char во вторичном потоке, скопировать в него элемент массива и затем вызвать free() для указателя?

По-видимому, с free() нет возвращаемого значения, поэтому я не могу понять, как обеспечить успешное выполнение вызова.

// Main thread
char *ptr = NULL;
char *array1[1] = {0};

ptr = (char *) malloc (3 * sizeof (char));

strcpy (ptr, "hi");

array1[0] = ptr;

CmtWriteTSQData (queue, array1, 1, 0 NULL);    

// Secondary thread
char *array2[1] = {0};

CmtReadTSQData (queue, array2, 1, 0, 0);

printf ("%s", array2[0]);  // Prints "hi"

free (array2[0]);  // Does this work?

1 Ответ

2 голосов
/ 25 апреля 2020

Короткий ответ - да.

Когда вы звоните malloc(), вы просите операционную систему предоставить вам часть полезной памяти некоторого минимального размера, и операционная система отвечает, передавая вам указатель, который является просто целым числом, представляющим виртуальный адрес этого куска памяти.

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

Операционная система не заботится о том, какой поток запрашивает память, и не заботится о том, какой поток отдает назад. Когда malloc() возвращает указатель в процессе, его могут использовать все потоки в этом процессе, а когда один из потоков free() указывает этот указатель, эта область памяти становится недействительной для всех потоков в процессе.

Я не знаю, как ведут себя функции CmtWriteTSQData() и CmtReadTSQData(), но пока printf("%p\n",ptr) в main и printf("%p\n",array2[0]) во вторичном потоке дают одинаковое шестнадцатеричное значение, ваш код хорош.

Надеюсь, это поможет!

...