|
|
  |
Олимпиада программистов, Чистый С |
|
|
|
Mar 22 2013, 07:30
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
igorle, замечания обдумываю, но вот например не ясно почему "покрошится" strlen от NULL? Это же просто 0 что собственно эквивалентно "\0" realloc можно вызывать с NULL, но у меня оно конечно не к селу ни к городу, однако realloc и NULL вполне себе ничего и есть причины так делать. Вот еще вариант ,но єто практически максимум того на что способен мой "мозг". Проверки и исключения пока не прикручивал ,важно понять это правильная идея или нет!? Код #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h>
void str_cpy (char **a, const char * b) { char * tmp = NULL; int size_str = strlen(b)+1; tmp = realloc(tmp, size_str); memmove (tmp, b, size_str); free (*a); *a = tmp; }
void str_cat (char **a, const char *b){ int size_str_1 = strlen(b); int size_str_2 = strlen(*a); *a = realloc(*a, size_str_1 + size_str_2 + 1); memmove (*a + size_str_2, b, size_str_1 + 1); }
int main() { char *s = NULL;
str_cpy(&s, "Hola Mola"); str_cpy(&s, s+5); str_cat(&s," World"); return 0; }
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Mar 22 2013, 07:52
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Цитата(Буратино @ Mar 22 2013, 11:30)  ...не ясно почему "покрошится" strlen от NULL? Это же просто 0 что собственно эквивалентно "\0" Чтобы почуствовать разницу, забегите вот этот код: Код static void foo(char *str) { printf("%p\n", str); }
int main(void) { foo(NULL); foo("\0"); return 0; } После этого попытайтесь объяснить, почему ваше утверждение неверно. По поводу всего остального. Я подписал обязательство, согласно которому, если станет известно что я консультирую участников конкурса Холы, то я должен буду вернуть полученую от них приемию. А я премию уже потратил на детальки. Так что дальше - самостоятельно. Адью
|
|
|
|
|
Mar 22 2013, 11:28
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Если бы я мог как-то обезапасить строку от изменений на ее текущем месте, то получилось бы интереснее, но я так понимаю, что кроме как выделить память под строку и перелить в это мето данные не получится гарантировать ее сохранность! Создать в памяти резервирование под существующую строку (то есть под то место где она текущая лежит) так же не получится ибо наверное на архитектуре завязано много. Склеивать строки нельзя на пустом месте, нужно быть уверенным в том что это склейка разместится в свободном и безопасном пространстве. Что касается strlen, то мне нужно посмотреть как она, функция, сделана.
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Mar 22 2013, 13:08
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(federal @ Mar 22 2013, 15:29)  Буратино, какой же ты деревянный все таки  Я лично был свидетелем того, как тигр в зоопарке сожрал резинового утенка, как вор и бандит становится президентом страны и как можно штуку баксов потратить на туфельки. А уж Дуремаров разного сорта и помола, я столько раз встречал, что Вы даже просто статистически ничего для меня не значите.
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Mar 25 2013, 11:29
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
igorle, Вы наверное хотели написать Код '\0' а не Код "\0" Вот код который печатает трижды NULL Код void foo(char *str) { printf("%s \n", str ); }
int main(void) { foo(NULL); foo('\0'); foo(0); return 0; } Код stdout: (null) (null) (null) Вот некая реализация strlen Код /* * Copyright (C) 2002 Manuel Novoa III * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */
#include "_string.h"
#ifdef WANT_WIDE # define Wstrlen wcslen #else # define Wstrlen strlen #endif
size_t Wstrlen(const Wchar *s) { register const Wchar *p;
for (p=s; *p; p++);
return p - s; } libc_hidden_weak(Wstrlen) На первый взгляд ничего криминального в передаче NULL в функцию нет, но те не менее strlen c NULL компилится с ошибкой.
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Mar 25 2013, 14:18
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Я Вас теряю. Вы пишите Цитата не ясно почему "покрошится" strlen от NULL? Это же просто 0 что собственно эквивалентно "\0" Когда я объясняю, в чем разница между 0 и "\0", вы говорите Цитата igorle, Вы наверное хотели написать '\0' а не "\0" Нет. Вы написали "\0", поэтому я говорил об "\0", а не об '\0'. Логично, да? После этого я даю вам пример, где распечатываю поинтер (%p), и показываю в чем разница между 0 и "\0", а вы печатаете совсем другой пример, где распечатываете строку (%s) и даете совсем другие аргументы. Я не улавливаю ход Вашей мысли.
|
|
|
|
|
Mar 25 2013, 18:15
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(Буратино @ Mar 25 2013, 20:41)  Кое-что почитал и думаю что нулевой указатель нельзя использовать с strlen, потому что нельзя разименовывать нулевой указатель. нулевой указатель нельзя использовать потому, что он обязан не указывать на любой обект программы, т.е. то, на что он указывает, явно не будет чем-то осмысленным. strlen(NULL) у вас вряд ли компилируется с ошибкой, скорее с предупреждением. а вот в процессе выполнения этого кода результат будет непредсказуем. точнее, если платформа вам хорошо знакома - результат можно предсказать, но он будет явно бессмысленным, т.к. по адресу памяти 0x0000 у вас наверняка никакой строки нет.
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Mar 26 2013, 07:22
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Цитата(Буратино @ Mar 25 2013, 19:41)  Сори, но я имел в виду именно '\0', не строковой литерал. Кое-что почитал и думаю что нулевой указатель нельзя использовать с strlen, потому что нельзя разименовывать нулевой указатель. Абсолютно верно. NULL означает, что объект находится по адресу ноль. Обычно - защищенная область. Как поется в песне "Ай-ай-ай туда нельзя"
|
|
|
|
|
Mar 27 2013, 20:33
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Жаль что больше нет времени. 28го все закончится( Вот моя последняя реализация. Прокачал защиту от NULL, оптимизировал некоторые участки и обдумал траблу с перекрытием данных в строках. Код #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h>
void str_cpy ( char **a, const char * b ) {
int size_src; char overlap; if ( b ) size_src = strlen( b ) + 1; else return; overlap = (*a <= b && *a + size_src >= b) || (b <= *a && b + size_src >= *a); *a = realloc( *a, size_src ); if ( overlap ) for (*a += size_src, b += size_src; size_src--; *--*a = *--b); else memcpy( *a, b, size_src ); }
void str_cat ( char **a, const char *b ){ int size_src, size_des; if ( *a ) size_des = strlen( *a ); else size_des = 0; if ( b ) size_src = strlen( b ); else return; *a = realloc( *a, size_src + size_des + 1 ); memmove ( *a + size_des, b, size_src + 1 ); }
int main() { char *s = NULL; str_cpy( &s, "Hola Mola" ); str_cpy( &s, s+5 ); str_cat( &s," World" ); return 0; } Очень интересно как правильно, ждем ответ ответ на этот вопрос от организаторов!  (EDIT: Утром немного допилил и исправил ошибки)
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Mar 28 2013, 05:19
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Буратино @ Mar 28 2013, 00:33)  обдумал траблу с перекрытием данных в строках. А чего её обдумывать? Посмотрите реализацию memmove. В ней всё уже обдумано: если нет перекрытия то вызывается memcpy. Оптимальнее вряд ли напишете. Я тоже отправил свой вариант в день размещения этой темы, но никакого ответа пока так и не получил. Завтра могу показать.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 28 2013, 06:01
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Цитата(demiurg_spb @ Mar 28 2013, 09:19)  Я тоже отправил свой вариант в день размещения этой темы, но никакого ответа пока так и не получил. Это странно. Они всегда отвечают если не в тот же день, то на следующий. Скажите, пожалуйста, свой емэйл. Можно частично. Я им прямо сейчас позвоню и спрошу как так получилось, что не ответили.
|
|
|
|
|
Mar 28 2013, 06:05
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(igorle @ Mar 28 2013, 10:01)  Это странно. Они всегда отвечают если не в тот же день, то на следующий. Скажите, пожалуйста, свой емэйл. Можно частично. Я им прямо сейчас позвоню и спрошу как так получилось, что не ответили. Отправлял и с demiurg_spb @ _ _ _.ru и с ___ @ kipspb.ru
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|