c-Valgrind内存泄漏和无效自由错误



我正试图解析一个输入,以便我的简单shell程序执行。尽管它按预期工作,但我遇到了**valgrind内存泄漏和无效的free((错误**。我试图弄清楚这个问题,但没有成功,提前感谢

#cisfun$ /bin/ls -l
token: /bin/ls
arg_list[0]: /bin/ls
token: -l
arg_list[1]: -l
token: (null)
cmd: /bin/ls
total 204
-rwxrw-r-- 1 vagrant vagrant    104 Jul  2 12:39 AUTHORS
-rwxrw-r-- 1 vagrant vagrant     23 Jun 14 16:25 README.md
-rw-rw-r-- 1 vagrant vagrant    575 Jul  4 08:25 execute.c
-rw-rw-r-- 1 vagrant vagrant    197 Aug 13 09:17 free_arg.c
-rwxr-xr-x 1 vagrant vagrant 142144 Jul  3 05:04 hbtn_ls
-rw-rw-r-- 1 vagrant vagrant    810 Aug 13 09:15 parse_arg.c
-rwxrw-r-- 1 vagrant vagrant    789 Jul  4 12:05 puts.c
-rwxrwxr-x 1 vagrant vagrant  27888 Aug 13 09:15 shell
-rwxrw-r-- 1 vagrant vagrant   1186 Aug 13 10:47 shell.c
-rwxrw-r-- 1 vagrant vagrant    398 Jul  4 10:29 shell.h
-rw-rw-r-- 1 vagrant vagrant    156 Jul  4 08:31 sig_handler.c
#cisfun$ ^Z
==8999== Invalid free() / delete / delete[] / realloc()
==8999==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==8999==    by 0x109423: free_arg (free_arg.c:12)
==8999==    by 0x10991C: main (shell.c:77)
==8999==  Address 0x4a4f040 is 0 bytes inside a block of size 120 free'd
==8999==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==8999==    by 0x10990D: main (shell.c:76)
==8999==  Block was alloc'd at
==8999==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==8999==    by 0x48DD573: getdelim (iogetdelim.c:62)
==8999==    by 0x1097EB: main (shell.c:47)
==8999==
==8999==
==8999== HEAP SUMMARY:
==8999==     in use at exit: 11 bytes in 2 blocks
==8999==   total heap usage: 8 allocs, 8 frees, 2,227 bytes allocated
==8999==
==8999== 11 bytes in 2 blocks are definitely lost in loss record 1 of 1
==8999==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==8999==    by 0x109528: parse_arg (parse_arg.c:29)
==8999==    by 0x109843: main (shell.c:54)
==8999==
==8999== LEAK SUMMARY:
==8999==    definitely lost: 11 bytes in 2 blocks
==8999==    indirectly lost: 0 bytes in 0 blocks
==8999==      possibly lost: 0 bytes in 0 blocks
==8999==    still reachable: 0 bytes in 0 blocks
==8999==         suppressed: 0 bytes in 0 blocks
==8999==
==8999== For lists of detected and suppressed errors, rerun with: -s
==8999== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

这是我的主要功能

47         nread = getline(&line, &len, stdin);
48         if (nread == -1)
49             break;
50
51         if (line[nread - 1] == 'n')
52             line[nread - 1] = '';
53
54         arg_list = parse_arg(line);
55
56         cmd = arg_list[0];
57         printf("cmd: %sn", cmd);
58         if (cmd == NULL || *cmd == '')
59             continue;
60
61
62
63         if (stat(cmd, &st) == 0)
64         {
65             execute(arg_list, prog_name);
66         }
67         else
68         {
69             perror(prog_name);
70         }
71     }
72
73     if (isatty(STDIN_FILENO))
74         _puts("n");
75
76     free(line);
77     free_arg(arg_list);
78     return (0);

以及Parse_arg((和free_arg((函数;

7 char **parse_arg(char *arg)
8 {
9     char **arg_list;
10     char *str, *token;
11     int i, j = 1;
12
13     arg_list = malloc(sizeof(*arg_list) * j);
14     if (arg_list == NULL)
15         return (NULL);
16
17     for (i = 0, str = arg; ;str = NULL, i++)
18     {
19         token = strtok(str, " ");
20         printf("token: %sn", token);
21
22         if (token == NULL)
23         {
24             arg_list[i] = NULL;
25             break;
26         }
27         else
28         {
29             arg_list[i] = malloc(sizeof(char) * strlen(token) + 1);
30             if (arg_list[i] == NULL)
31             {
32                 while (i--)
33                     free(arg_list[i]);
34
35                 free(arg_list);
36                 return (NULL);
37             }
38             arg_list[i] = token;
39             printf("arg_list[%d]: %sn", i, arg_list[i]);
40         }
41         arg_list = realloc(arg_list, sizeof(*arg_list) * ++j);
42         if (arg_list == NULL)
43              return (NULL);
44
45     }
46     return (arg_list);
47 }
6 void free_arg(char **arg)
7 {
8     int i;
9
10     for (i = 0; arg[i] != NULL; i++)
11     {
12         free(arg[i]);
13     }
14     free(arg);
15 }

arg_list包含指向line的指针。所以line被释放了两次。一次在主(76(,一次在free_arg。删除主函数中的free(line)行。

29  arg_list[i] = malloc(sizeof(char) * strlen(token) + 1);
30  if (arg_list[i] == NULL)
31  {
32      while (i--)
33          free(arg_list[i]);
34
35      free(arg_list);
36      return (NULL);
37  }
// arg_list[i]` points at an allocated buffer.
38  arg_list[i] = token;
// But, ignore that buffer and reassign it to a local variable
// The allocated buffer is now orphaned

您可能想要`strcpy(arg_list[i],token(;

最新更新