以下代码用于查找c
中基本shell的可执行文件的路径。如您所见,我动态分配path
变量,然后检查路径是否存在(通过辅助函数lstat
中的cmd_exists
)。然后我返回路径变量。我的问题是,这会导致内存泄漏,因为path
永远不会被释放。在我返回它的值之前我无法释放路径,并且截至目前我无法想出释放已分配的内存的任何方法。如果有人能帮助我,我会很感激。谢谢
char * find_path(char * mypath, char * command){
char * token = strtok(mypath, "#");
while(token != NULL){
/*token size + 1 (for /) + command size*/
char * path = calloc(strlen(token)+1+strlen(command)+1, sizeof(char));
strcat(path, token);
strcat(path, "/");
strcat(path, command);
if(cmd_exists(path) == 1){
return path;
}
token = strtok(NULL, "#");
}
return NULL;
}
这确实是C的问题之一。内存所有权可能相当困难,因为C ++中没有RAII概念(基本上没有自动析构函数)。
我看到3个解决方案如何解决这个问题:
char *
,而是添加char *
和size_t
参数(size_t
表示char *
缓冲区的大小)。然后你的find_path函数可以填充这个缓冲区。有关具有此行为的函数,请参阅https://en.cppreference.com/w/cpp/string/byte/strncpy。这种方法的问题是如果缓冲区不够大,你的函数需要返回一个失败,调用者必须传递一个更大的缓冲区。一些Windows函数通过让函数返回“预期”缓冲区大小来解决这个问题,所以如果调用失败(因为缓冲区不够大),调用者可以使用返回值来查看缓冲区应该有多大,并分配更大的缓冲区。我的首选解决方案取决于实际情况。如果存在有意义的最大缓冲区大小(例如,最大文件路径),我将采用第三种替代方案。我会采取第二种选择是最大缓冲区大小很难预测。在任何情况下,我都不会使用第一种替代品。
你需要在两个可能的地方有free
。
cmd_exists
返回false,则需要释放路径。cmd_exists
返回true,则需要在调用方法中有空。1.
while(token != NULL){
/*token size + 1 (for /) + command size*/
char * path = calloc(strlen(token)+1+strlen(command)+1, sizeof(char));
strcat(path, token);
strcat(path, "/");
strcat(path, command);
if(cmd_exists(path) == 1){
return path;
}
free(path); // 1. Here
token = strtok(NULL, "#");
}
return NULL;
2.
char *temp = find_path(...);
.....//do your stuff
if (temp) free(temp);
您可以要求呼叫者释放内存:
// in caller
char * s = find_path("/mypath", "command");
// do something about `s`
free(s);