以下代码摘自《操作系统:三个简单的书》一书。代码使我感到困惑。我知道execvp
正常运行时永远不会返回。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/wait.h>
int
main(int argc, char *argv[])
{
int rc = fork();
if (rc < 0) {
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) {
// child: redirect standard output to a file
close(STDOUT_FILENO);
open("./p4.output", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
// now exec "wc"...
char *myargs[3];
myargs[0] = strdup("wc"); // program: "wc" (word count)
myargs[1] = strdup("p4.c"); // argument: file to count
myargs[2] = NULL; // marks end of array
execvp(myargs[0], myargs); // runs word count
} else {
// parent goes down this path (original process)
int wc = wait(NULL);
assert(wc >= 0);
}
return 0;
}
我使用Valgrind检查内存泄漏。上面的代码没有内存泄漏。当我删除execvp
行时,它将明确检测到丢失:2个块中的8个字节。为什么是这样?
Valgrind命令:
valgrind --leak-check=full ./a.out
当我使用命令valgrind --trace-children = yes --leak-check = full ./p4
==15091== Memcheck, a memory error detector
==15091== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15091== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==15091== Command: ./p4
==15091==
==15092== Memcheck, a memory error detector
==15092== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15092== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==15092== Command: /usr/bin/wc p4.c
==15092==
==15092==
==15092== HEAP SUMMARY:
==15092== in use at exit: 0 bytes in 0 blocks
==15092== total heap usage: 36 allocs, 36 frees, 8,809 bytes allocated
==15092==
==15092== All heap blocks were freed -- no leaks are possible
==15092==
==15092== For counts of detected and suppressed errors, rerun with: -v
==15092== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==15091==
==15091== HEAP SUMMARY:
==15091== in use at exit: 0 bytes in 0 blocks
==15091== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==15091==
==15091== All heap blocks were freed -- no leaks are possible
==15091==
==15091== For counts of detected and suppressed errors, rerun with: -v
==15091== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[root cpu-api]#
无论我分配了多少字节,堆摘要始终显示:== 15092 ==总堆使用量:36个分配,36个空闲,分配的8,809个字节
首先,让我们讨论一下Valgrind报告为“绝对丢失”的情况:如果在程序终止之前所有对分配内存的引用都丢失了,Valgrind将报告分配的内存为“绝对丢失”。换句话说,如果您的程序达到一种状态,在该状态下已分配的内存由于不存在指向该内存的有效指针而无法释放,则将被视为“绝对丢失”。
exec()
系列功能用新的过程映像替换当前过程映像。这意味着调用进程当前正在运行的程序将被新程序替换,并具有新初始化的堆栈,堆和(初始化和未初始化的)数据段。