C:fork()动态内存分配

时间:2017-08-21 07:30:17

标签: c memory-leaks dynamic-memory-allocation

请考虑以下代码段:

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);
}

输出:

  • taskArray:[11489296]
  • main:[21060]:[11489296] [7]
  • 父母:[21060]:[11489296] [7]
  • 儿童:[21061]:[11489296] [7]
  • 儿童:[21061]:[11489296] [10]
  • 父母:[21060]:[11489296] [7]
  • 父母:[21060]:[11489328] []

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

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

修改

我知道很多行为都是未定义的,而且代码在逻辑上并不正确,但它仍然可以运行并执行。问题是试图理解为什么形成错误的,不合逻辑的代码能够解决问题。这是为什么。

1 个答案:

答案 0 :(得分:1)

你应该记住,在'C'课程中,fork通过复制虚拟分页表来创建一个新进程,这样孩子就会看到与父代完全相同的值(通常页面会读取 - 只保护)。但是,只要您开始在子内存空间中写入,相应页面条目的物理映射就会更新为指向新位置,数据将被复制到新位置。

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

  • 虽然virtual地址的物理映射可能不同,但{{1}}地址看起来是一样的,是的,值会有所不同。
子中的

free()释放分配给子节点的内存,不影响分配给父节点的内存。

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

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

  • 不要!! 您只是从记忆中读取的值不是您认为的,即使是合法的,也可以通过写入来破坏它。无论是孩子还是父母。

在父级中我有大量的内存泄漏,因为没有free()。如果程序在循环中运行直到有人杀死进程,请帮助理解此内存泄漏的副作用。还请告知当进程被杀死时会发生什么,是否释放了所有内存?

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