Стандартный способ инициализации и использования структуры - PullRequest
0 голосов
/ 28 января 2019

Допустим, мне нужно проанализировать строку в 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 ...)я должен создать конструктор и метод деструктора вместо этого?

1 Ответ

0 голосов
/ 28 января 2019

Я бы сделал отдельный «конструктор» для самого типа:

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;
}

То есть независимо от того, передаете ли вы новый или существующий объект в функцию анализа, он всегда будет очищать старую память.

Ни один из этого кода не должен быть на стороне вызывающего,им не нужно знать детали реализации вашей структуры, чтобы использовать ее.

...