请考虑以下代码段:
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);
}
输出:
请帮我确认/理解以下几点
修改
我知道很多行为都是未定义的,而且代码在逻辑上并不正确,但它仍然可以运行并执行。问题是试图理解为什么形成错误的,不合逻辑的代码能够解决问题。这是为什么。
答案 0 :(得分:1)
你应该记住,在'C'课程中,fork
通过复制虚拟分页表来创建一个新进程,这样孩子就会看到与父代完全相同的值(通常页面会读取 - 只保护)。但是,只要您开始在子内存空间中写入,相应页面条目的物理映射就会更新为指向新位置,数据将被复制到新位置。
指针地址是虚拟的,因此即使地址看起来相同,子节点和父节点也有不同的值。
virtual
地址的物理映射可能不同,但{{1}}地址看起来是一样的,是的,值会有所不同。free()释放分配给子节点的内存,不影响分配给父节点的内存。
在calloc中我只分配了1个项目,但是我正在尝试使用[1000]它仍然可以解决,因为即使没有分配给我的内存仍然存在。然而它的风险可能会导致未来的核心转储。同样在孩子中我在free()之后使用内存它仍然有效。
在父级中我有大量的内存泄漏,因为没有free()。如果程序在循环中运行直到有人杀死进程,请帮助理解此内存泄漏的副作用。还请告知当进程被杀死时会发生什么,是否释放了所有内存?