2015-05-13 3 views
1

Я пытаюсь написать функцию, которая генерирует заголовок HTTP-запросов. Я в настоящее время есть что-то вродеВозврат char * или использование memcpy?

static char* genHeader() { 
    return("POST/HTTP/1.1\r\n\ 
      Host: www.example.com\r\n\ 
      Content-Type: application/x-www-form-urlencoded\r\n\r\n"); 
} 

Я знаю, что это также может быть сделано:

static void genHeader(char *header) { memcpy(header, ...); } 

Который один ближе к «каноническому» способ генерирования заголовка? Во втором методе мне нужно освободить память, тогда как в первом я бы не стал, правильно?

Благодаря

ответ

5

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

#define HTTP_HEADER \ 
    "POST/HTTP/1.1\r\n" \ 
    "Host: www.example.com\r\n" \ 
    "Content-Type: application/x-www-form-urlencoded\r\n\r\n" 

вместо функции.

Ситуации, когда вам нужно динамически генерировать заголовок, например, потому что Host изменение, будут требуют второго решения, так как вам нужно будет выделить достаточно мест для заголовка, а затем создать строку заголовка.

И в таком случае было бы лучше, если функция позаботится о возврате указателя на вновь выделенную и строковую строку, но да, вызывающий отвечает за вызов free().

Также нет необходимости в круглых скобках в вашем заявлении return, что делает код трудным для чтения.

0

Это не совсем правильный вопрос, так как ваш пример генерирует заголовок, который является буквальным. В реальной жизни я предполагаю, что он будет иметь динамический контент. Вопрос заключается в том, как создавать динамическое содержимое строк. Чтобы генерировать переменные размер и строки содержимого, вам нужно будет выделить его в кучу (если вы не хотите выполнять действительно напряженную работу со статическими пулами памяти). Это наводит на мысль о необходимости

static char * MakeHeader(...); 

и сообщите вызывающему абоненту, что он был освобожден.

0

Есть несколько способов для функции, чтобы произвести строку:

  • Возвращает указатель на статический, как и в первом примере. Это просто и не требует управления памятью, но содержимое строки должно быть известно во время компиляции.

  • Копировать строку в буфер, переданном при вызове, так как sprintf() делает, например:

    void genHeader(char* buffer, size_t length); 
    

    Это будет писать символы в buffer пока length не будет достигнуто. Он делает genHeader() проще, заставляя вызывающего абонента выделять память. Однако, возможно, не удастся заранее знать, сколько памяти выделяется, и в этом случае вызывающий абонент будет либо выделять слишком много, либо слишком мало. Вы могли бы получить genHeader(), если требуется размер буфера, если buffer имеет значение NULL или какой-либо вариант.

  • Выделяет строку самостоятельно:

    char* genHeader(); 
    

    Это позволяет избежать большинство проблем выше, давая Вам полный контроль над процессом выделения достаточного объема памяти для хранения контента. Однако вызывающий абонент теперь вынужден освобождать память.

Я бы выбрал третий вариант для любого динамического контента.