假设我需要解析 C 中的一行并填充一个结构,例如:
line = "GET /hello HTTP/1.1rn";
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...),我是否应该创建一个构造函数和析构函数方法?
我会为类型本身创建一个单独的"构造函数":
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 函数,它都将始终清理旧内存。
这些代码都不应该在调用方端,他们不需要知道结构的实现细节来使用它。