#c #struct #malloc
Вопрос:
Я пытаюсь создать HTTP-ответ, используя некоторые пользовательские библиотеки. Библиотечной функции требуется указатель на массив пользовательской структуры HttpHeader
. Ниже кода приведен фрагмент справочной страницы. Мне было интересно, как его инициализировать, чтобы Content-Length
заполнить имя, а значение заполняет значение, тогда следующим HttpHeader
в массиве будет NULL
указатель, указанный на справочной странице. Ниже приведен код, который у меня есть в настоящее время, но в моей системе возникает ошибка при mallocing исходной памяти для заголовков:
ошибка: ожидаемое выражение перед ‘HttpHeader’
HttpHeader ** заголовки = malloc(sizeof(** HttpHeader));
Как исправить эту ошибку?
Мой код:
void populate_header(HttpHeader** headers, char* value) {
headers[0]->name = malloc(sizeof(char) * strlen("Content-Length"));
headers[0]->value = malloc(sizeof(char) * strlen(value));
strcpy(headers[0]->name, "Content-Length");
strcpy(headers[0]->value, value);
}
char* process_address(char** addrContents) {
HttpHeader** headers = malloc(sizeof(*HttpHeader));
char* body = NULL;
char* response = NULL;
if (strcmp(addrContents[1], "validate") == 0) {
populate_header(headers, "0");
if (!check_expression(addrContents[2])) {
response = construct_HTTP_response(400, "Bad Request", headers, body);
} else {
response = construct_HTTP_response(200, "OK", headers, body);
}
} else if (strcmp(addrContents[1], "integrate") == 0) {
if (!check_expression(addrContents[2])) {
populate_header(headers, "0");
response = construct_HTTP_response(400, "Bad Request", headers, body);
} else {
response = construct_HTTP_response(200, "OK", headers, body);
}
} else {
populate_header(headers, "0");
response = construct_HTTP_response(400, "Bad Request", headers, body);
}
//printf("Response: %sn", response);
return response;
}
Страница руководства:
headers
points to an array of HttpHeader* (see below), each containing the name of value of a HTTP header. The last entry in headers will be a NULL
pointer.
HttpHeader
A HttpHeader is defined as follows:
typedef struct {
char* name;
char* value;
} HttpHeader;
Memory for name and value is allocated separately.
Комментарии:
1. Правильный ответ будет зависеть от того, получает ли
construct_HTTP_response
он право собственности на какуюheaders
-либо точку.2. Вы не выделяете достаточно места внутри
populate_header
. Поскольку строки C заканчиваются нулевым байтом, вам необходимо выделить strlen 1 . А еще лучше, используйтеstrdup
.
Ответ №1:
sizeof(*HttpHeader)
проблема. *
разыменовывает указатель. HttpHeader
это тип, нет смысла разыменовывать тип.
Вместо этого вы хотите sizeof(HttpHeader*)
. Это тип, который является указателем на a HttpHeader
.
malloc(sizeof(HttpHeader*));
выделяет место только для одного указателя. Если вы хотите выделить место для более чем одного заголовка, вам нужно умножить. Например, если вам нужно место для пяти заголовков: malloc(sizeof(HttpHeader*) * 5);
Наконец, предполагается, что массив завершается нулем, чтобы он знал, когда прекратить чтение по массиву. Выделите на один указатель больше, чем вам нужно, и установите для конечного элемента значение null.
// Space for two headers, the last is a null.
HttpHeader** headers = malloc(sizeof(*HttpHeader) * 2);
headers[1] = NULL;
Аналогично, строки в C заканчиваются нулем. Вы должны выделить на один байт больше, чем длина строки.
sizeof(char)
определено равным 1, вы можете его не использовать.
void populate_header(HttpHeader** headers, char* value) {
headers[0]->name = malloc(strlen("Content-Length") 1);
headers[0]->value = malloc(strlen(value) 1);
strcpy(headers[0]->name, "Content-Length");
strcpy(headers[0]->value, value);
}
А еще лучше, используйте strdup
.
void populate_header(HttpHeader** headers, char* value) {
headers[0]->name = strdup("Content-Length");
headers[0]->value = strdup(value);
}