我正在用C写一个shell。这个shell max接收并执行由20个管道分隔的命令(|)。这些命令运行得很顺利,但是当我用Valgrind进行内存检查时,我得到的输出如下:
==64422== HEAP SUMMARY:
==64422== in use at exit: 24 bytes in 1 blocks
==64422== total heap usage: 9 allocs, 13 frees, 4,156 bytes allocated
==64422==
==64422== 24 bytes in 1 blocks are definitely lost in loss record 1 of 1
==64422== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==64422== by 0x491260E: strdup (strdup.c:42)
==64422== by 0x1098C5: split_commands (in /home/furkan/Masaüstü/hw02/my)
==64422== by 0x109C93: main (in /home//Masaüstü/hw02/my)
==64422==
==64422== LEAK SUMMARY:
==64422== definitely lost: 24 bytes in 1 blocks
==64422== indirectly lost: 0 bytes in 0 blocks
==64422== possibly lost: 0 bytes in 0 blocks
==64422== still reachable: 0 bytes in 0 blocks
==64422== suppressed: 0 bytes in 0 blocks
==64422==
==64422== For lists of detected and suppressed errors, rerun with: -s
==64422== ERROR SUMMARY: 11 errors from 8 contexts (suppressed: 0 from 0)
在这部分代码中,我解析了用管道分隔的命令(|).然后我删除了在开始时发现的间隙,并以strtrim结束。Valgrind说这部分存在内存泄漏。然而,我无法弄清楚为什么strdup()函数会产生内存泄漏以及如何阻止此泄漏。
char *strtrim(char *str) {
char *end;
// Trim leading space
while (isspace(*str)) {
str++;
}
if (*str == 0) { // All spaces?
return str;
}
// Trim trailing space
end = str + strlen(str) - 1;
while (end > str && isspace(*end)) {
end--;
}
// Write new null terminator
*(end+1) = 0;
return str;
}
void split_commands(char *input, char **commands, int *num_commands) {
int count = 0;
const char delimiter[] = "|";
char *token;
// Count the number of commands
for (int i = 0; input[i]!= '\0'; i++) {
if(input[i] == '|')
count++;
}
*num_commands = count + 1;
// Split input into commands
token = strtok(input, delimiter);
for (int i = 0; i < *num_commands; i++) {
(commands)[i] = strtrim(strdup(token));
token = strtok(NULL, delimiter);
}
}
1条答案
按热度按时间2w2cym1i1#
另一种方法是“就地编辑”字符串缓冲区以不更改指针值。
下面是你的函数的一个替代:
你可以决定这是否变成
void strtrim()
...而且,你可以节省对字符串进行标记的代码:
有很多人相信
**commands
足够大,可以存储所有的指针,也许你可以考虑使用链表而不是数组来存储每个子字符串。