jenya7 0 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба Есть такая функция. uint32_t XML_PARSER_FindElementEnd(char *xml_str, char* el_name, char* pchr) { uint32_t el_size = strlen(el_name); char buf[el_size+4]; memcpy(&buf[0], "<", 1); memcpy(&buf[1], el_name, el_size); memcpy(&buf[el_size+1], "/>\0", 3); pchr = strstr(xml_str, buf); if(pchr == NULL) return 0; else return 1; } Внутри функции pchr принимает правильное значение, все прекрасно. Проверяем uint32_t XML_PARSER_NewElement(char *xml_str, char *parent, char* el_name) { char *pchr_test=NULL; if (!XML_PARSER_FindElementEnd(xml_str, parent, pchr_test)); return 0; } pchr_test остается 0. Подскажите где ошибка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба Подскажите где ошибка. В функцию передаётся копия указателя, поэтому вы изменяете копию. Передавать надо указатель на указатель. uint32_t XML_PARSER_FindElementEnd(char *xml_str, char* el_name, char** pchr) { uint32_t el_size = strlen(el_name); char buf[el_size+4]; memcpy(&buf[0], "<", 1); memcpy(&buf[1], el_name, el_size); memcpy(&buf[el_size+1], "/>\0", 3); *pchr = strstr(xml_str, buf); if(*pchr == NULL) return 0; else return 1; } uint32_t XML_PARSER_NewElement(char *xml_str, char *parent, char* el_name) { char *pchr_test=NULL; if (!XML_PARSER_FindElementEnd(xml_str, parent, &pchr_test)); return 0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба Подскажите где ошибка.Ошибка в вашем стойком нежелании учить язык путем чтения документации. Потратьте наконец один день на чтение Кернигана и Ритчи. Аргументы в функцию передаются по значению. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
novikovfb 17 20 декабря, 2016 Опубликовано 20 декабря, 2016 (изменено) · Жалоба Есть такая функция. // pchr - входное значение типа "указатель на char" uint32_t XML_PARSER_FindElementEnd(char *xml_str, char* el_name, char* pchr) { uint32_t el_size = strlen(el_name); char buf[el_size+4]; memcpy(&buf[0], "<", 1); memcpy(&buf[1], el_name, el_size); memcpy(&buf[el_size+1], "/>\0", 3); pchr = strstr(xml_str, buf);// игнориуем исходное значение, заменяем его на результат strstr if(pchr == NULL) return 0; else return 1; } Внутри функции pchr принимает правильное значение, все прекрасно. Проверяем uint32_t XML_PARSER_NewElement(char *xml_str, char *parent, char* el_name) { char *pchr_test=NULL; if (!XML_PARSER_FindElementEnd(xml_str, parent, pchr_test)); return 0; } pchr_test остается 0. Подскажите где ошибка. При "проверке" внутри функции значение pchr меняется так, как написано, но нигде не сказано компилятору, что значение надо оттуда вытащить наружу в вызывающую функцию. Для языка C можно переписать так: // ppchr - входное значение типа "указатель на указатель на char" uint32_t XML_PARSER_FindElementEnd(char *xml_str, char* el_name, char** ppchr) { uint32_t el_size = strlen(el_name); char buf[el_size+4]; memcpy(&buf[0], "<", 1); memcpy(&buf[1], el_name, el_size); memcpy(&buf[el_size+1], "/>\0", 3); *ppchr = strstr(xml_str, buf);// по адресу ppchr записываем результат strstr if(ppchr == NULL) return 0; else return 1; } uint32_t XML_PARSER_NewElement(char *xml_str, char *parent, char* el_name) { char *pchr_test=NULL; if (!XML_PARSER_FindElementEnd(xml_str, parent, &pchr_test));// передаем адрес pchr_test - указатель на указатель на char return 0; } для языка C++ есть более интересная возможность - передача по ссылке Изменено 20 декабря, 2016 пользователем novikovfb Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ucMike 0 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба if (!XML_PARSER_FindElementEnd(xml_str, parent, pchr_test)); return 0; Точка с запятой в первой строчке - так задумано? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба if (!XML_PARSER_FindElementEnd(xml_str, parent, pchr_test)); return 0; Точка с запятой в первой строчке - так задумано? описка. При "проверке" внутри функции значение pchr меняется так, как написано, но нигде не сказано компилятору, что значение надо оттуда вытащить наружу в вызывающую функцию. упс... точно. надо указатель на указатель использовать. char** pchr. спасибо. Ошибка в вашем стойком нежелании учить язык путем чтения документации. Потратьте наконец один день на чтение Кернигана и Ритчи. Аргументы в функцию передаются по значению. его пример другим наука. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба uint32_t XML_PARSER_FindElementEnd(char *xml_str, char* el_name, char* pchr) { char buf[el_size+4]; memcpy(&buf[0], "<", 1); memcpy(&buf[1], el_name, el_size); memcpy(&buf[el_size+1], "/>\0", 3); } какая то магия понаписана может попроще для людей сделать ? char buf[ el_size + sizeof( "</>" ) ]; sprintf( buff, "<%s/>", el_name ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба какая то магия понаписана может попроще для людей сделать ? char buf[ el_size + sizeof( "</>" ) ]; sprintf( buff, "<%s/>", el_name ); вы считаете что монструозная sprint это попроще? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 20 декабря, 2016 Опубликовано 20 декабря, 2016 · Жалоба кстати сделал проверку #if USE_MEMCPY memcpy(&buf[0], "<", 1); memcpy(&buf[1], el_name, el_size); memcpy(&buf[el_size+1], ">\0", 2); #else memset(buf, '\0', el_size+4); strcat(buf,"<"); strcat(buf, el_name); strcat(buf, ">"); #endif посмотрел листинг - размер кода с strcat почти в 2 раза меньше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
conan 0 21 декабря, 2016 Опубликовано 21 декабря, 2016 (изменено) · Жалоба посмотрел листинг - размер кода с strcat почти в 2 раза меньше.Зато memcpy скорее всего быстрее uint32_t el_size = strlen(el_name); char buf[el_size+4]; Хорошо, что в C++ пока нет такой мерзости как локальные массивы переменного размера Изменено 21 декабря, 2016 пользователем conan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arhiv6 14 21 декабря, 2016 Опубликовано 21 декабря, 2016 · Жалоба conan, а чем они Вам не нравятся? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 21 декабря, 2016 Опубликовано 21 декабря, 2016 · Жалоба Зато memcpy скорее всего быстрее uint32_t el_size = strlen(el_name); char buf[el_size+4]; Хорошо, что в C++ пока нет такой мерзости как локальные массивы переменного размера я думал над этим. тут конечно есть опасность stack overflow. но я думаю есть механизмы контроля. вроде регистр SP доступен. можно посмотреть где мы находимся в стаке и вычислить сколько осталось места? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 21 декабря, 2016 Опубликовано 21 декабря, 2016 · Жалоба Не, массивы переменной длины иногда могут быть полезны. Но этот код является наглядной иллюстрацией к "если бы строители строили дома так же, как программисты пишут программы, то первый же залетный дятел порушил бы цивилизацию": uint32_t el_size = strlen(el_name); char buf[el_size+4]; Если входной файл вдруг будет испорчен - можно легко нарваться на переполнение стека. но я думаю есть механизмы контроля. вроде регистр SP доступен. можно посмотреть где мы находимся в стеке и вычислить сколько осталось места?И где тут такие проверки? Просто возвращайте 0 если el_size больше какого-то предела, на который у вас достаточно стека и в который заведомо укладываются все необходимые вам элементы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 21 декабря, 2016 Опубликовано 21 декабря, 2016 (изменено) · Жалоба Не, массивы переменной длины иногда могут быть полезны. Но этот код является наглядной иллюстрацией к "если бы строители строили дома так же, как программисты пишут программы, то первый же залетный дятел порушил бы цивилизацию": uint32_t el_size = strlen(el_name); char buf[el_size+4]; Если входной файл вдруг будет испорчен - можно легко нарваться на переполнение стека. И где тут такие проверки? Просто возвращайте 0 если el_size больше какого-то предела, на который у вас достаточно стека и в который заведомо укладываются все необходимые вам элементы. допустим размер стака 1К. А el_size 0.5К - вроде как места хватает. но я не знаю насколько заполнен стак до выделения места под el_size. есть код до него. вложенные ф-ции и.т.д и.т.п. поэтому я думаю правильней сделать END_OF_STACK – SP. Изменено 21 декабря, 2016 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
conan 0 21 декабря, 2016 Опубликовано 21 декабря, 2016 · Жалоба conan, а чем они Вам не нравятся? Не эстетично же. Как минимум sizeof выносится в runtime допустим размер стака 1К. А el_size 0.5К - вроде как места хватает. но я не знаю насколько заполнен стак до выделения места под el_size. есть код до него. вложенные ф-ции и.т.д и.т.п. поэтому я думаю правильней сделать END_OF_STACK – SP. Чушь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться