gpt4 book ai didi

C:fork()动态内存分配

转载 作者:行者123 更新时间:2023-11-30 20:20:34 25 4
gpt4 key购买 nike

请考虑以下代码片段:

struct TASKS {char  taskid[4];};

struct TASKS *taskArray;

int main()
{
for(;;)
{
taskArray = (struct TASKS *) calloc(1, sizeof(struct TASKS));
printf("\ntaskArray:[%d]\n",taskArray);fflush(stdout);
strcpy(taskArray[1000].taskid,"7");
printf("main:[%d] : [%d][%s]\n",getpid(),taskArray,taskArray[1000].taskid);fflush(stdout);

returnvalue = fork();

if (returnvalue == 0)
{
printf("Child:[%d] : [%d][%s]\n",getpid(),taskArray,taskArray[1000].taskid);fflush(stdout);
free(taskArray);
strcpy(taskArray[1000].taskid,"10");
sleep(3);
printf("Child:[%d] : [%d][%s]\n",getpid(),taskArray,taskArray[1000].taskid);fflush(stdout);
exit(1);
}

if (returnvalue != 0)
{
printf("Parent:[%d] : [%d][%s]\n",getpid(),taskArray,taskArray[1000].taskid);fflush(stdout);
sleep(6);
printf("Parent:[%d] : [%d][%s]\n",getpid(),taskArray,taskArray[1000].taskid);fflush(stdout);
taskArray = (struct TASKS *) calloc(1, sizeof(struct TASKS));
printf("Parent:[%d] : [%d][%s]\n",getpid(),taskArray,taskArray[1000].taskid);fflush(stdout);
}
}

exit(1);
}

输出:

  • 任务数组:[11489296]
  • 主要:[21060]:[11489296][7]
  • 父级:[21060] : [11489296][7]
  • 子级:[21061] : [11489296][7]
  • 子级:[21061] : [11489296][10]
  • 父级:[21060] : [11489296][7]
  • 父级:[21060] : [11489328][]

请帮我确认/理解以下几点

  • 指针地址是虚拟的,因此即使地址看起来相同,子级和父级也具有不同的值。
  • 子进程中的 free() 会释放分配给子进程的内存,并且不会影响分配给父进程的内存。
  • 在 calloc 中,我只分配了 1 个项目,但是我尝试使用 [1000],它仍然有效,因为即使没有分配给我,内存仍然存在。然而,它有风险,并且可能会在将来导致核心转储。同样,在 child 中,我在 free() 之后使用内存,它仍然有效。
  • 在父级中,由于没有 free(),因此存在巨大的内存泄漏。如果程序永远循环运行直到有人杀死该进程,请帮助理解此内存泄漏的副作用。另请告知当进程被终止时会发生什么,它是否释放所有内存?

编辑:

我知道许多行为是未定义的,并且代码在逻辑上不正确,但它仍然有效并执行。问题是试图理解为什么格式不正确、不合逻辑的代码能够运行以及为什么。

最佳答案

您应该记得在“C”类(class)中,fork 通过复制虚拟分页表来创建一个新进程,这样子进程将看到与父进程完全相同的值(通常页面将具有只读保护)。然而,一旦您开始在子内存空间中写入,相应页面条目的物理映射就会更新以指向新位置,并且数据将被复制到新位置。

指针地址是虚拟的,因此即使地址看起来相同,子级和父级也具有不同的值。

  • 虚拟地址看起来是一样的,尽管它们的物理映射可能不同,而且值也会不同。

子进程中的 free() 会释放分配给子进程的内存,并且不会影响分配给父进程的内存。

  • 是的,它不会影响父级,因为它将在子级的虚拟空间和子级该空间的物理映射中完成。 Free仅意味着操作内存中的指针。因此,释放的节点的内容仍然可以映射到父空间(直到您开始覆盖它)。

在 calloc 中,我只分配了 1 个项目,但是我尝试使用 [1000] 并且它仍然有效,因为即使没有分配给我,内存仍然存在。然而,它有风险,并且可能会在将来导致核心转储。同样,在 child 中,我在 free() 之后使用内存,它仍然有效。

  • 不要!!你只是从内存中读取值,这不是你想象的那样,即使是合法的,或者通过写入来破坏它。无论是 child 还是 parent 。

在父级中,由于没有 free(),因此存在巨大的内存泄漏。如果程序永远循环运行直到有人杀死该进程,请帮助理解此内存泄漏的副作用。另请告知进程被终止时会发生什么,它是否释放所有内存?

  • 当一个进程被以任何方式杀死或正常退出时,它使用的所有内存通常都会返回到操作系统以供重用。至少在我所知道的所有通用操作系统中是这样。

关于C:fork()动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45791518/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com