在此 shell 模拟中,我的内存泄漏在哪里未被释放?
Where is my memory leak not being freed in this shell simulation?
我无法在使用 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
在start
中,您使用malloc
分配内存并将其分配给一个指针,然后您使用NULL
覆盖指针的内容。您现在已经忘记了 malloc
ed 的记忆。
所以,在这个循环中:
for(index = 0; index < numberArgs + 1; index++) {
writableUsersArgs[index] = (char*)malloc(maxArgLength*sizeof(char));
}
writableUsersArgs
的每个成员都分配了一个指向由 malloc
保留的唯一内存块的指针,包括数组成员 writableUsersArgs[numberArgs]
。
几行之后,你写
writableUsersArgs[index] = NULL;
她的index
和numberArgs
一样值。您现在已经丢失了对 writableUsersArgs[index]
之前指向的 malloc
ed 块的所有引用。
您可能想要 运行 循环 while index < numberArgs
.
这仅说明了 start
中丢失的区块。除非您显示该代码,否则我不能对 commandDelimeter
或 createArgsArray
中丢失的块说任何话。但我怀疑这是同样的问题。
最后的注释:我认为在调用 fork
/exec
之前不需要复制 creareArgsArray
返回的字符串
我无法在使用 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
在start
中,您使用malloc
分配内存并将其分配给一个指针,然后您使用NULL
覆盖指针的内容。您现在已经忘记了 malloc
ed 的记忆。
所以,在这个循环中:
for(index = 0; index < numberArgs + 1; index++) {
writableUsersArgs[index] = (char*)malloc(maxArgLength*sizeof(char));
}
writableUsersArgs
的每个成员都分配了一个指向由 malloc
保留的唯一内存块的指针,包括数组成员 writableUsersArgs[numberArgs]
。
几行之后,你写
writableUsersArgs[index] = NULL;
她的index
和numberArgs
一样值。您现在已经丢失了对 writableUsersArgs[index]
之前指向的 malloc
ed 块的所有引用。
您可能想要 运行 循环 while index < numberArgs
.
这仅说明了 start
中丢失的区块。除非您显示该代码,否则我不能对 commandDelimeter
或 createArgsArray
中丢失的块说任何话。但我怀疑这是同样的问题。
最后的注释:我认为在调用 fork
/exec
creareArgsArray
返回的字符串