C 标记字符串时内存泄漏
我用C编写了一个程序,它对输入字符串进行标记,当用户输入“exit”时,它将退出该程序 它正确地标记了字符串,但是,当我用valgrind测试我的程序时,我发现一些内存泄漏。唯一一种不会出现内存泄漏的情况是在编译并执行之后,我立即退出 以下是valgrind的输出: 这是我的程序代码:C 标记字符串时内存泄漏,c,linux,string,memory-leaks,tokenize,C,Linux,String,Memory Leaks,Tokenize,我用C编写了一个程序,它对输入字符串进行标记,当用户输入“exit”时,它将退出该程序 它正确地标记了字符串,但是,当我用valgrind测试我的程序时,我发现一些内存泄漏。唯一一种不会出现内存泄漏的情况是在编译并执行之后,我立即退出 以下是valgrind的输出: 这是我的程序代码: int main() { /* Main Function Variables */ char *buf; char *savecpy = NULL;
int main() {
/* Main Function Variables */
char *buf;
char *savecpy = NULL;
char *token;
size_t num_chars;
size_t bufsize = 2048;
int run = 1;
int tok_count = 0;
int cmp;
/* Allocate memory for the input buffer. */
buf = (char *) malloc(sizeof(char) * bufsize);
/*main run loop*/
while(run) {
/* Print >>> then get the input string */
printf(">>> ");
num_chars = getline(&buf, &bufsize, stdin);
cmp = strcmp(buf, "exit\n");
if (num_chars > 1) {
/* Tokenize the input string */
if (cmp != 0) {
/* Display each token */
savecpy = strdup(buf);
while((token = strtok_r(savecpy, " ", &savecpy))) {
printf("T%d: %s\n", tok_count, token);
tok_count++;
}
}
/* If the user entered <exit> then exit the loop */
else {
run = 0;
break;
}
}
tok_count = 0;
}
/*Free the allocated memory*/
free(buf);
return 1;
}
intmain(){
/*主要函数变量*/
char*buf;
char*savecpy=NULL;
字符*令牌;
大小/数量/字符;
尺寸=2048;
int run=1;
int tok_计数=0;
int-cmp;
/*为输入缓冲区分配内存*/
buf=(char*)malloc(sizeof(char)*bufsize);
/*主回路*/
while(运行){
/*打印>>>然后获取输入字符串*/
printf(“>>>”);
num_chars=getline(&buf,&bufsize,stdin);
cmp=strcmp(buf,“退出”\n);
如果(字符数>1){
/*标记输入字符串*/
如果(cmp!=0){
/*显示每个令牌*/
savecpy=strdup(buf);
while((token=strtok_r(savecpy,“,&savecpy))){
printf(“T%d:%s\n”,tok_计数,令牌);
托库计数++;
}
}
/*如果用户输入,则退出循环*/
否则{
run=0;
打破
}
}
tok_计数=0;
}
/*释放分配的内存*/
免费(buf);
返回1;
}
导致valgrind内存泄漏的问题可能是什么?我正在释放输入字符串的内存,但仍有内存泄漏。
savecpy
应被释放。如图所示:
获取新字符串的内存
使用malloc(3),并可以使用free(3)释放
通过strtok\u r
第三个参数后,无法释放savecpy
,因为此函数修改指针。我宁愿传递这样的东西
char* ptr;
strtok_r(..,.., &ptr);
然后您可以释放
savecpy
似乎您从未释放过savecpy
我在程序结束时释放了savecpy,但我得到了一个munmap块无效指针。您在程序结束时释放了buf
。在将savecpy
重新分配给不同的内存地址之前,必须释放savecpy
指向的内存,因为如果在此之前不释放它,则不再有任何需要释放的内存块记录。(然而,我不知道你为什么一开始就觉得有必要复制。)