Мне нужно освободить массив malloc'ed, который я передал в качестве аргумента execve()?

Я создал простую программу-оболочку, которая
_отображает подсказку
_получает пользовательский ввод с помощью readline()
_разбивает ввод на слова в зависимости от того, где во входной строке встречаются пробелы
_ затем слова помещаются в массив (который обрабатывается MALLOC);
_fork() используется для создания дочернего процесса
_i затем передайте этот массив для вызова программы из дочернего процесса с помощью execve()
execve(myarray[0], myarray, env); и текущий процесс ждет его.

МОЙ ВОПРОС: Нужно ли мне освобождать MALLOC-память myarray ?
Вот часть кода

  child_pid = fork();
 42                 if (child_pid == -1)
 43                 {
 44                         perror(argv[0]);
 45                         free(linebuffer);
 46                         return (2);
 47                 }
 48
 49                 if (child_pid == 0)
 50                 {
 51                         /*strsplit() returns MALLOC'd array*/
 52                         splitted_str = _strsplit(linebuffer, ' ');
 53
 54                         if (execve(splitted_str[0], splitted_str, env) == -1)
 55                         {
 56                                 perror(argv[0]);
 57                                 
             /*Function that frees a NULL terminated array*/  
free_array(splitted_str);
 58                                 free(linebuffer);
 59
 60                                 return (2);
 61                         }
 62                 }
 63                 else
 64                 {
 65                         wait(NULL);
 66                 }
execve() заменить текущий образ процесса, так куда звонить free()? После успешного execve() ваш код больше не выполняется. Или вы хотите освободить его в родительском процессе после fork()?
dimich 16.11.2022 04:37

Если execve() успешно, может ли это вызвать утечку памяти из-за массива malloc?

Nwaburu Emeka Christian 16.11.2022 04:41

Проведите эксперимент.

Allan Wind 16.11.2022 04:47

Если это один процесс (он не вызывает fork()), это не приведет к утечке памяти. Но вы упомянули, что текущий процесс ждет этого, поэтому я сомневаюсь. Пожалуйста, покажите полный код, где массив обрабатывается, вызывается execve() и что "ждет этого".

dimich 16.11.2022 04:48

В настоящее время я тестирую свой код с помощью valgrind, и я продолжаю получать утечки памяти, но не могу понять, откуда они. Следовательно, вопрос @AllanWind

Nwaburu Emeka Christian 16.11.2022 04:49

Да, вам нужно освободить память в родительском процессе. Вопрос, который я связал, содержит более подробную информацию.

Allan Wind 16.11.2022 04:51

@AllanWind, этот вопрос больше касается поведения fork, которое не используется в этом вопросе. (ну, во всяком случае, не так, как было описано)

M.M 16.11.2022 04:53

@MM Это говорит о exec. Может я что-то упускаю?

Allan Wind 16.11.2022 04:54

OP, пожалуйста, уточните вопрос - execve заменяет вызывающий процесс новым процессом, «родительского процесса» нет. Если вы используете fork, укажите это в вопросе

M.M 16.11.2022 04:55

@M.M Я предположил, что родитель «и текущий процесс ждет его».

Allan Wind 16.11.2022 04:56

Форк использовался для создания дочернего процесса. Затем в родительском процессе используется wait()

Nwaburu Emeka Christian 16.11.2022 05:03

@NwaburuEmekaChristian Массив выделяется в родительском процессе до fork () или в дочернем процессе после?

dimich 16.11.2022 05:07

@dimich Выделяется после fork() в дочернем процессе

Nwaburu Emeka Christian 16.11.2022 05:11

Я включил часть кода

Nwaburu Emeka Christian 16.11.2022 05:21

@NwaburuEmekaChristian Вы можете оставить free_array(splitted_str), оно будет выполнено, если execve() потерпит неудачу. Конечно, если вы не используете его позже в дочернем процессе. И результат проверки execve() избыточен: он либо возвращает -1, либо не возвращает.

dimich 16.11.2022 06:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
16
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нужно ли мне освобождать MALLOC-память myarray?

Вам не нужно освобождать его в процессе, который вызывает execve(). В случае успеха эта функция заменяет весь образ процесса новым, так что нечего освобождать и нет способа его освободить. Для целей новой программы второй аргумент main() и строки в этом массиве не выделяются динамически и не могут быть освобождены. С другой стороны, при сбое execve() вызывающий процесс должен немедленно завершиться, и этого достаточно для удовлетворения любой потребности в освобождении выделенной памяти в этом процессе.

Однако, если вы выполняете выделение до forking, что, похоже, вы и делаете, то вам, вероятно, нужно освободить память в процессе, который не вызывает execve(). Вы можете не беспокоиться, если этот процесс все равно скоро завершится, но если он будет продолжать работать бесконечно, обрабатывая неопределенное количество дополнительных команд, вам следует освободить память, когда вы закончите с ним.

Почему вы должны немедленно прекратить работу в случае execve() неудачи? Я никогда не слышал этого раньше.

root 16.11.2022 09:43

@root: какая альтернатива? Ребенок был создан для выполнения определенной программы. Если он не может его выполнить, какое дерьмо делать вместо этого? Найти исходный код, скомпилировать и выполнить его? Применить машинное обучение, чтобы решить, как записать недостающий исходный код?

Jonathan Leffler 16.11.2022 11:16

@root, я удивлен, что ты никогда этого не слышал. Это совершенно обычно и вполне разумно. Альтернативой является продолжение дочерним процессом кода родительского процесса, что редко, если вообще когда-либо, имеет смысл. Более того, если родитель wait() за дочернего, то он будет продолжать делать это до тех пор, пока дочерний не завершится, даже если дочерний делает что-то отличное от того, для чего он был разветвлен.

John Bollinger 16.11.2022 15:45

Я думал, вы имеете в виду какую-то техническую причину (например, не гарантируется, что образ памяти останется неповрежденным). Я помню, как видел оболочку, которая при запуске myprogram проходила каждый путь в PATH и пробовала execve("path/myprogram", ...), пока не добилась успеха.

root 16.11.2022 19:22

Другие вопросы по теме