Перенаправление указателя на массив структур

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