以下代码用于在c
中查找基本shell的可执行文件的路径。如您所见,我动态分配了path
变量,然后检查路径是否存在(通过辅助函数lstat
中的cmd_exists
)。然后,我返回path变量。我的问题是,这将导致内存泄漏,因为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;
}
答案 0 :(得分:4)
这确实是C的问题之一。内存所有权可能非常困难,因为C ++中没有RAII概念(本质上没有自动析构函数)。
我看到3种解决方案:
char *
,而是添加char *
和size_t
自变量(size_t
指示char *
缓冲区的大小(以字符为单位)。然后,您的find_path函数可以填充此缓冲区。有关此行为的功能,请参见https://en.cppreference.com/w/cpp/string/byte/strncpy。这种方法的问题在于,如果缓冲区不够大,则您的函数需要返回失败,并且调用方必须传递更大的缓冲区。某些Windows函数通过使函数返回“预期的”缓冲区大小来解决此问题,因此,如果调用失败(因为缓冲区不够大),则调用者可以使用返回值查看缓冲区应该有多大,并分配更大的缓冲区。我的首选解决方案取决于实际情况。如果存在有意义的最大缓冲区大小(例如最大文件路径),我将采用第三种选择。我会采取的第二种选择是最大的缓冲区大小很难预测。无论如何,我永远不会使用第一种选择。
答案 1 :(得分:2)
您需要在两个可能的位置放置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);
答案 2 :(得分:0)
您可以要求呼叫者释放内存:
// in caller
char * s = find_path("/mypath", "command");
// do something about `s`
free(s);