比方说,我需要在C语言中解析一行并填充以下结构:
line = "GET /hello HTTP/1.1\r\n";
typedef struct {
char* method;
char* path;
char* protocol;
} http_request_line;
parse_http();
我想调用一个返回http_request_line
的函数。我不确定几件事:
我应该在哪里初始化结构分配内存?应该在我的调用方法(例如main()
)中并为其指定一个指针,以便函数将其填满吗?还是应该在parse_http()
中并返回它的副本?
request_http_line parse_http(char* line);
request_http_line* parse_http(char* line);
void parse_http(char* line, request_http_line *rhl);
由于结构具有长度不确定的字段(例如,该方法可以具有可变长度,例如GET,HEAD ...),因此我应该创建一个构造函数和析构函数方法吗?
答案 0 :(得分:2)
我会为类型本身创建一个单独的“构造函数”:
request_http_line* create_empty_request (void)
{
request_http_line* obj = malloc( sizeof *obj );
obj->method = NULL;
obj->path = NULL;
obj->protocol = NULL;
return obj;
}
您现在可以利用free(NULL)
定义明确的事实,并使解析函数像这样:
request_http_line* parse_http (request_http_line* request_line, const char* line)
{
free(request_line->method);
free(request_line->path);
free(request_line->protocol);
request_line->method = malloc (...);
...
return request_line;
}
意味着无论您将新对象还是现有对象传递给parse函数,它都将始终清除旧内存。
此代码中的任何一个都不应该在调用方,他们不需要知道使用它的结构的实现细节。