LINUX.ORG.RU

переменая си

 ,


0

1

Не могу понять, куда копать. Имеется следующий код (это часть, выделил только то, что имеет отношение к вопросу с отладочной печатью):

void httpClientReqBuf (char *url, unsigned char **buff);

char *URL1 = "http://192.168.0.10:9999/json_discret1";
char *URL2 = "http://192.168.0.10:9999/json_discret2";

unsigned char *buff1;
unsigned char *buff2;

while (1)
{
    httpClientReqBuf (URL1, &buff1);
    printf ("buff1 %s\n", buff1);        // здесь печать buff1 проходит нормально
		
    httpClientReqBuf (URL2, &buff2);     
    printf ("buff2 %s\n", buff2);
    
    printf ("buff1 %s\n", buff1);       // здесь печать buff1 не верна
    printf ("buff2 %s\n", buff2);
}

вывод

buff1 {"DI_tag1":"1","DI_tag2":"0"}
buff2 {"DI_tag3":"0","DI_tag4":"1"}
buff1 �
buff2 {"DI_tag3":"0","DI_tag4":"1"}

buff1 {"DI_tag1":"1","DI_tag2":"0"}
buff2 {"DI_tag3":"0","DI_tag4":"1"}
buff1 {"DI_tag3":"0","DI_tag4":"1"}
buff2 {"DI_tag3":"0","DI_tag4":"1"}

buff1 {"DI_tag1":"1","DI_tag2":"0"}
buff2 {"DI_tag3":"0","DI_tag4":"1"}
buff1 {"DI_tag3":"0","DI_tag4":"1"}
buff2 {"DI_tag3":"0","DI_tag4":"1"}

Значение строки buff1 сразу за вызовом функции httpClientReqBuf (URL1, &buff1) верно, что и вижу при отладочной печати. Но после вызова функции httpClientReqBuf (URL2, &buff2) значение buff1 меняет свое значение и в разные запросы принимает всякий мусор, может принять и значение buff2. Объясните пожалуйста почему так происходит, почему затирается значение buff1 в памяти? Как мне это правильно реализовать ?



Последнее исправление: salik (всего исправлений: 3)

Ответ на: комментарий от anonymous

Если я правильно понял, то да - этот кусок кода реализован в отдельном потоке.

salik
() автор топика
Ответ на: комментарий от anonymous

Инкрементирую анонимуса.

ТС, ты бы лучше код своей httpClientReqBuf пришпилил.

Eddy_Em ☆☆☆☆☆
()

Предположения, по куску текста:

1. Если по тексту смотреть, то buff1 и buff2 остались неинициализированными и указывают на случайную память.

2. unsigned char *buff1; - объявили; httpClientReqBuf (URL1, &buff1); - какой адрес передали? тогда уж без &

anonymous
()
Ответ на: комментарий от anonymous

2. unsigned char *buff1; - объявили; httpClientReqBuf (URL1, &buff1); - какой адрес передали? тогда уж без &

Это дренной, негодный анонимус. Он не умеет в сишку. Он не знает, что передача с & в этом случае намекает на то, что функция сама положит в этот указатель что надо? на это же намекает и

void httpClientReqBuf (char *url, unsigned char **buff);
где **buff

anonymous
()
Ответ на: комментарий от Eddy_Em

функциональное программирование - убрал )

весь код httpClientReqBuf не интересен, в нем пробрасываю buff (char**) в callback вызов http_request_done, который принимает в качестве аргумента void *arg.

httpClientReqBuf и http_request_done

void httpClientReqBuf (char *url, unsigned char **buff)
{
    // не интересно
    req = evhttp_request_new(http_request_done, buff); // 
    // не интересно
}


void	http_request_done(struct evhttp_request *req, void *arg)
			
{
    struct evbuffer *in_evb = evhttp_request_get_input_buffer(req);	// получаем входной буфер evhttp запроса
    size_t len = evbuffer_get_length(in_evb);						// получаем длину буфера
    *(unsigned char**)arg = evbuffer_pullup (in_evb, -1);	        // приведение void* к нашему типу, выталкиваем буфер 
    (*(unsigned char**)arg) [len] = '\0';							
}

salik
() автор топика
Ответ на: комментарий от anonymous

буффер в httpClientReqBuf() не создается. httpClientReqBuf(char *url, unsigned char **buff) принимает в качестве аргумента **buff, который потом передается http_request_done() где и формируется буффер.

salik
() автор топика
Ответ на: комментарий от salik
req = evhttp_request_new(http_request_done, buff)

это работает так - делается запрос и после этого вызывается http_request_done() и ей в качестве нашего парметра передается buff.

http_request_done() имеет следующий прототип

void http_request_done(struct evhttp_request *req, void *arg)
в качестве аргумента void*arg она и принимает наш buff.

salik
() автор топика
Ответ на: комментарий от salik

А какой контракт у evbuffer_pullup? То что вы получили указатель на какой-то внутренний буфер еще не означает что он теперь никем кроме вас использоваться не будет. Выделите свой буфер и скопируйте туда.

ricie
()
Ответ на: комментарий от salik

Нет, именно там он и создается. Показывай код.

anonymous
()
Ответ на: комментарий от anonymous

Не нужно хамить. Я все подробно разложил.

конкретно вот здесь buff и формируется

*(unsigned char**)arg = evbuffer_pullup (in_evb, -1);

salik
() автор топика
Ответ на: комментарий от ricie

наверно Вы правы. evbuffer_pullup это библиотека libevent. Попробую реализовать используя еще один промежуточный буфер.

salik
() автор топика

Про выделение памяти уже сказали? )

aol ★★★★★
()
Ответ на: комментарий от ricie

Всем спасибо! Понял, где ошибка. Еще раз спасибо)

salik
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.