gui*_*ouz 5 c memory malloc free strtok
我使用strtok()编写了一个简单的url解析器.这是代码
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *protocol;
char *host;
int port;
char *path;
} aUrl;
void parse_url(char *url, aUrl *ret) {
printf("Parsing %s\n", url);
char *tmp = (char *)_strdup(url);
//char *protocol, *host, *port, *path;
int len = 0;
// protocol agora eh por exemplo http: ou https:
ret->protocol = (char *) strtok(tmp, "/");
len = strlen(ret->protocol) + 2;
ret->host = (char *) strtok(NULL, "/");
len += strlen(ret->host);
//printf("char at %d => %c", len, url[len]);
ret->path = (char *)_strdup(&url[len]);
ret->path = (char *) strtok(ret->path, "#");
ret->protocol = (char *) strtok(ret->protocol, ":");
// host agora é por exemplo address.com:8080
//tmp = (char *)_strdup(host);
//strtok(tmp, ":");
ret->host = (char *) strtok(ret->host, ":");
tmp = (char *) strtok(NULL, ":");
if(tmp == NULL) {
if(strcmp(ret->protocol, "http") == 0) {
ret->port = 80;
} else if(strcmp(ret->protocol, "https") == 0) {
ret->port = 443;
}
} else {
ret->port = atoi(tmp);
}
//host = (char *) strtok(NULL, "/");
}
/*
*
*/
int main(int argc, char** argv) {
printf("hello moto\n");
aUrl myUrl;
parse_url("http://teste.com/Teste/asdf#coisa", &myUrl);
printf("protocol is %s\nhost is %s\nport is %d\npath is %s\n", myUrl.protocol, myUrl.host, myUrl.port, myUrl.path);
return (EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我使用strtok()很多,所以我可以"切片"网址.我不需要支持不同于http或https的网址,因此它完成的方式解决了我的所有问题.我担心的是(这是在嵌入式设备上运行) - 我是在浪费内存吗?当我写的东西像
ret->protocol = (char *) strtok(tmp, "/");
Run Code Online (Sandbox Code Playgroud)
然后打电话
ret->protocol = (char *) strtok(ret->protocol, ":");
Run Code Online (Sandbox Code Playgroud)
我首先将指针ret->协议保留在内存中吗?我想也许我应该设置第一次调用tmp指针,调用strtok指向ret-> protocol到字符串的右边部分(第二次调用)然后free(tmp).
什么应该是使用strtok的最佳方式?
Ben*_*tto 22
要直接回答你的问题,strtok只返回一个指向你给它作为输入的字符串内部位置的指针 - 它没有为你分配新的内存,所以不需要在它给你的任何指针上调用free回来了.
对于它的价值,您还可以查看"strchr"和"strstr",它们是在字符串中搜索单个字符或序列的非破坏性方式.
另请注意,此处的内存分配存在问题 - 您使用strdup()在解析函数中分配新字符串,然后将该内存块的片段分配给"ret"字段.因此,你的调用者将负责释放strdup的字符串,但由于你只是在ret中隐式地传回该字符串,调用者需要神奇地知道要传递给free的指针.(可能是ret-> protocol,但可能不是,具体取决于输入的外观.)
strtok修改了字符串,用NULL替换指定的字符.由于C中的字符串以NULL结尾,现在看来您的原始指针指向较短的字符串,即使原始字符串仍然存在并且仍然占用相同数量的内存(但字符替换为NULL).我认为,字符串的结尾包含一个双NULL.
简短的回答是:保持指向字符串缓冲区开头的指针,并在解析时指向另一个指向字符串的"当前"指针.当您使用strtok或以其他方式迭代字符串时,您更新"当前"指针但保留单独的开始指针.当你完成后,free()开始指针.没有记忆泄露.