【发布时间】:2021-12-14 20:54:26
【问题描述】:
我找不到在使用 valgrind 工具的 shell 模拟 C 程序中没有释放内存泄漏的地方。我还使用 gdb 调试器运行了我的程序。 writableUsersArgs 包含 "/usr/bin/vim" 作为第一个元素,NULL 作为第二个元素。使用调试器,它显示数组writableUsersArgs 被释放了两次。
包含内存泄漏的函数
int start(char* command){
// pid uses status's value behind the scenes
int status;
int maxArgLength = 0;
int argLength = 0;
int index;
// Split the user's command into seperate strings wherever the command has spaces
char** usersArgs = commandDelimeter(command);
int numberArgs = countArgs(command);
// Calculate maxArgLength to allocate correct amount of memory
for(index = 0; index < numberArgs; index++) {
argLength = countLongestArg(usersArgs[index]);
if(argLength > maxArgLength) {
maxArgLength = argLength;
}
}
// Allocate memory for the array that gets passed to exec() function
char* writableUsersArgs[numberArgs+1];
for(index = 0; index < numberArgs + 1; index++) {
writableUsersArgs[index] = (char*)malloc(maxArgLength*sizeof(char));
}
// Copy the strings from the read only array to a writable array of strings
for(index = 0; index < numberArgs; index++) {
strcpy(writableUsersArgs[index], usersArgs[index]);
}
// Last entry of array must be NULL for exec() function to work properly
writableUsersArgs[index] = NULL;
// Create a child process
pid_t pid = fork();
if(pid == -1) {
printf("Error forking");
return -1;
} else if(pid == 0) {
// Jumps into new child process
execv(writableUsersArgs[0], writableUsersArgs);
return 2;
} else {
// Waits for child process to terminate before proceeding
wait(&status);
for(index = 0; index < numberArgs + 1; index++) {
free(usersArgs[index]);
free(writableUsersArgs[index]);
}
free(usersArgs);
return 1;
}
}
Valgrind 内存检查错误信息
==670== HEAP SUMMARY:
==670== in use at exit: 26 bytes in 2 blocks
==670== total heap usage: 73 allocs, 71 frees, 8,432 bytes allocated
==670==
==670== 13 bytes in 1 blocks are definitely lost in loss record 1 of 2
==670== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==670== by 0x10ABC3: createArgsArray (mysh.c:579)
==670== by 0x10A946: commandDelimeter (mysh.c:508)
==670== by 0x109DB0: start (mysh.c:269)
==670== by 0x109820: executeCommandWithArgs (mysh.c:151)
==670== by 0x109641: executeCommand (mysh.c:115)
==670== by 0x109542: insideShell (mysh.c:83)
==670== by 0x1094C3: main (mysh.c:63)
==670==
==670== 13 bytes in 1 blocks are definitely lost in loss record 2 of 2
==670== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==670== by 0x109EDB: start (mysh.c:281)
==670== by 0x109820: executeCommandWithArgs (mysh.c:151)
==670== by 0x109641: executeCommand (mysh.c:115)
==670== by 0x109542: insideShell (mysh.c:83)
==670== by 0x1094C3: main (mysh.c:63)
==670==
==670== LEAK SUMMARY:
==670== definitely lost: 26 bytes in 2 blocks
==670== indirectly lost: 0 bytes in 0 blocks
==670== possibly lost: 0 bytes in 0 blocks
==670== still reachable: 0 bytes in 0 blocks
==670== suppressed: 0 bytes in 0 blocks
【问题讨论】:
-
提供代码和错误消息的最佳方式是什么?
-
你看过我提供的链接了吗?
-
是的,我刚刚编辑了我的帖子。这是我第一次在 stackoverflow 上提问,所以我不知道提问包含代码的问题的正确方法。
标签: c memory-leaks valgrind