У Кернигана и Ритчи и у великого Гугля я ответ не нашёл.Собираю gcc под FreeBSD.
#include <stdlib.h>
#include <string.h>typedef struct {
char *remote_addr;
char *http_referer;
char *http_user_agent;
char *hid;
char *cn;
char *ref;
char *received_cookie;
char *generated_cookie;
} RequestPtr;void get_stat(RequestPtr *request)
{char *request_uri = "/hid=4237&cn=юПУ2ЮМХЕ. рЕЮРП нЦМХБН";
int i = 0, j = 0;
char *tmp_hid = (char*)malloc(16);while (*(request_uri+i)!='\0'){
if(*(request_uri+i) == 'h' && *(request_uri+i+1) == 'i' &&
*(request_uri+i+2) == 'd' && *(request_uri+i+3) == '='){
i+=4;
j = 0;
while (*(request_uri+i)!='&' && *(request_uri+i)!='\0'){
*(tmp_hid+j) = *(request_uri+i);
// request->hid[j] = *(request_uri+i);
i++;
j++;
}
*(tmp_hid+j) = '\0';
}
}
request->hid = tmp_hid;
free(tmp_hid);
}main()
{RequestPtr p, *request;
request = &p;get_stat(request);
printf("\n request.hid = %s", request->hid);
}
Хотелось бы избавиться от выделения памяти под временную строку и собирать результат сразу в элементе структуры вот так:
request->hid[j] = *(request_uri+i);Эта строка в коде закомментирована, но если раскомментировать, то программа нормально собирается, а при выполнении валится в кору.
1. Почему такое присваивание не срабатывает? Почему строку я присвоить могу, а символ не получается?
2. Как выделяется память под структуру? Понятно, что компилятор подсчитает сколько места надо под хранение указателей этой структуры, а под сами строки как выделяется память (и когда она освобождается) в процессе работы программы?
[...]
>char *tmp_hid = (char*)malloc(16);Откуда эта волшебная цифра 16 взялась?!
>
>while (*(request_uri+i)!='\0'){while (request_uri[i] != '\0') {
Кажется, так это должно выглядеть...
> if(*(request_uri+i) == 'h' && *(request_uri+i+1) == 'i'
>&& *(request_uri+i+2) == 'd' &&
>*(request_uri+i+3) == '='){Вместо *(request_uri+i+x) можно написать просто request[i+x], если ничего в три ночи не путаю.
А можно и вовсе использовать strncmp() и сравнивать сразу четыре символа за раз.
[...]
>Хотелось бы избавиться от выделения памяти под временную строку и собирать результат
>сразу в элементе структуры вот так:
>request->hid[j] = *(request_uri+i);
>
>Эта строка в коде закомментирована, но если раскомментировать, то программа нормально собирается,
>а при выполнении валится в кору.
>1. Почему такое присваивание не срабатывает? Почему строку я присвоить могу,
>а символ не получается?Что-то вы явно не так делаете. Сейчас не соображу что а самому лень разбираться (у меня почти пол-четвёртого ночи %))
>2. Как выделяется память под структуру? Понятно, что компилятор подсчитает сколько
>места надо под хранение указателей этой структуры, а под сами строки
>как выделяется память (и когда она освобождается) в процессе работы программы?Выделять динамически типа malloc(sizeof(struct)) и освобождать тоже вручную (ну или alloc() какой юзать). Под каждую строку член структуры выделять надо отдельно и освобождать тоже отдельно.
>[...]
>>char *tmp_hid = (char*)malloc(16);
>
>Откуда эта волшебная цифра 16 взялась?!Из утверждения, что значение hid в request_uri не будет длиннее 15 символов. Но это не важно в данном случае.
>>while (*(request_uri+i)!='\0'){
>
>while (request_uri[i] != '\0') {
>
>Кажется, так это должно выглядеть...Вы привели абсолютно эквивалентную форму записи. Можно и так записать.
>> if(*(request_uri+i) == 'h' && *(request_uri+i+1) == 'i'
>>&& *(request_uri+i+2) == 'd' &&
>>*(request_uri+i+3) == '='){
>
>Вместо *(request_uri+i+x) можно написать просто request[i+x], если ничего в три ночи не
>путаю.да, можно. Ваша запись более удобочитаема.
>А можно и вовсе использовать strncmp() и сравнивать сразу четыре символа за
>раз.Можно, но мне понравилось как делает Сысоев в исходниках nginx'a. Получается быстро и красиво. (По моему коду этого не скажешь :) )
>[оверквотинг удален]
>>сразу в элементе структуры вот так:
>>request->hid[j] = *(request_uri+i);
>>
>>Эта строка в коде закомментирована, но если раскомментировать, то программа нормально собирается,
>>а при выполнении валится в кору.
>>1. Почему такое присваивание не срабатывает? Почему строку я присвоить могу,
>>а символ не получается?
>
>Что-то вы явно не так делаете. Сейчас не соображу что а самому
>лень разбираться (у меня почти пол-четвёртого ночи %))Мне тоже интересно узнать :)
>>2. Как выделяется память под структуру? Понятно, что компилятор подсчитает сколько
>>места надо под хранение указателей этой структуры, а под сами строки
>>как выделяется память (и когда она освобождается) в процессе работы программы?
>
>Выделять динамически типа malloc(sizeof(struct)) и освобождать тоже вручную (ну или alloc() какой
>юзать). Под каждую строку член структуры выделять надо отдельно и освобождать
>тоже отдельно.Очень уж геморойно получается и неудобно. Прежде чем взять sizeof надо где-то уже результат получить, т.е. придётся создавать временные переменные (типа моей char *tmp_hid = (char*)malloc(16);). А это лишняя трата памяти. Проще уж так определить, благо максимальные длины каждой строки известны:
typedef struct {
char remote_addr[512]; /*цифры с потолка. для примера */
char http_referer[1024];
char http_user_agent[512];
char hid[16];
char cn[512];
char ref[1024];
char received_cookie[1024];
char generated_cookie[1024];
} RequestPtr;
>>[...]
>>>char *tmp_hid = (char*)malloc(16);
>>
>>request->hid = tmp_hid;
>> free(tmp_hid);
>>}этот код в принципе работать НЕБУДЕТ!!!
т.е он не верен! и даже если вы будете щас доказыать что вот у меня работает, это иллюзия.объясню в кратце. вы возвращаете структуру в которой есть указатель. а этот указатель ссылается на ОСВОБОЖДЕННОЕ место памяти! любой другой код с malloc займет это место без вопросов, и начнет туда записывать свои данные.