Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.07.2023, 20:59   #11
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 965
По умолчанию

Цитата:
Сообщение от Alar Посмотреть сообщение
раз скомипиловалось, значит всё правильно
да, но если в коде нету UB ))

например, в посте №7 есть минимум одно UB
Алексей1153 вне форума Ответить с цитированием
Старый 31.07.2023, 21:04   #12
Alar
Александр
Администратор
 
Аватар для Alar
 
Регистрация: 28.10.2006
Сообщений: 17,501
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
да, но
да я уж понял что программерфорум прийти поныть бесплатно.
Alar вне форума Ответить с цитированием
Старый 01.08.2023, 09:43   #13
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,550
По умолчанию

Кто такое UB? "Ужасная бомбёжка" ? "Угарный бред" ? "Unsigned binary"
digitalis вне форума Ответить с цитированием
Старый 01.08.2023, 09:47   #14
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 965
По умолчанию

Цитата:
Сообщение от digitalis Посмотреть сообщение
"Ужасная бомбёжка" ? "Угарный бред" ?
всё это подходит

undefined behavior - неопределённое поведение. Программа с UB - обычно неработоспособна сразу, но иногда (если сильно не повезло) это не сразу бывает заметно
Алексей1153 вне форума Ответить с цитированием
Старый 01.08.2023, 11:22   #15
Steelcraft
Форумчанин
 
Регистрация: 13.03.2023
Сообщений: 111
По умолчанию

Раз уж речь о чистом C, выдержка из стандарта ISO/IEC 9899:2018 (E):

Цитата:
3.4.3 undefned behavior - behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this document imposes no requirements.

Note 1 to entry: Possible undefned behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
У C++, разумеется, свои стандарты, но смысл термина схожий.

На собеседованиях от джуниора и выше обязательный вопрос, по вполне понятным причинам. Для стажеров незнание допускается, менторы по ходу научат.
Steelcraft вне форума Ответить с цитированием
Старый 04.08.2023, 11:20   #16
iXNomad
Пользователь
 
Регистрация: 06.01.2021
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Steelcraft Посмотреть сообщение
Раз уж речь о чистом C, выдержка из стандарта ISO/IEC 9899:2018 (E):



У C++, разумеется, свои стандарты, но смысл термина схожий.

На собеседованиях от джуниора и выше обязательный вопрос, по вполне понятным причинам. Для стажеров незнание допускается, менторы по ходу научат.
А если я специально такое сделал? Мне очень не нравилось, что зерно менялось каждую секунду, а не каждый вызов программы.
Это приводило к тому, что вызывая программу несколько раз в секунду (напр., $ ./psw gen 10 -l -L -d -s), это приводило к одному и тому же результату.
А так больше рандомности.

Код:
    ...
    unsigned long seed = time(NULL);
    unsigned long useless_garbage = (unsigned long) &useless_garbage;            // Вот это UB
    
    seed ^= (useless_garbage * (seed * 0xCAFE + useless_garbage % 0xBEEF))
             >> (seed % 0x4) * seed * 0x50BAD;
    
    for(int i = 0; i < FLAGS % 0x100; i++) {
        password[i] = randomChar(char_set, seed + i + (useless_garbage 
                                                      * seed + 0xF00D));
    }
    
    free(char_set);
    
    return password;
}

Последний раз редактировалось iXNomad; 04.08.2023 в 11:23.
iXNomad вне форума Ответить с цитированием
Старый 04.08.2023, 12:32   #17
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 965
По умолчанию

Цитата:
Сообщение от iXNomad Посмотреть сообщение
unsigned long useless_garbage = (unsigned long) &useless_garbage; // Вот это UB
тут UB нет, всего лишь адрес переменной привёлся к типу unsigned long и записался в эту переменную. Тут никакой гарантии на разное значение нет, а в релизе, скорее всего, компилятор будет просто константу использовать какую-нибудь.

UB тут:
Цитата:
Сообщение от iXNomad Посмотреть сообщение
reversed[length] = '\0';
ведь, я правильно понимаю, что reversed - это некий массив (точнее, указатель на первый элемент массива), а length - это длина массива в элементах?
В этом случае тут - выход за край массива
Алексей1153 вне форума Ответить с цитированием
Старый 04.08.2023, 14:34   #18
iXNomad
Пользователь
 
Регистрация: 06.01.2021
Сообщений: 45
По умолчанию

iXNomad,
Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
тут UB нет, всего лишь адрес переменной привёлся к типу unsigned long и записался в эту переменную. Тут никакой гарантии на разное значение нет, а в релизе, скорее всего, компилятор будет просто константу использовать какую-нибудь.

UB тут:

ведь, я правильно понимаю, что reversed - это некий массив (точнее, указатель на первый элемент массива), а length - это длина массива в элементах?
В этом случае тут - выход за край массива
1. Каждый раз адрес разный был на Linux.
Система же не может в 100% случаев гарантировать, что будет одинаковый адрес стека именно для этой программы при каждом запуске. Мало ли что на компе происходит.
Компилятор gcc.

2. Это вроде была длина строки как strlen. Без учёта '\0'.
Сама сигнатура функции уже была написана в условии задачи.

Последний раз редактировалось iXNomad; 04.08.2023 в 14:38.
iXNomad вне форума Ответить с цитированием
Старый 04.08.2023, 14:49   #19
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 965
По умолчанию

Цитата:
Сообщение от iXNomad Посмотреть сообщение
Это вроде была длина строки как strlen. Без учёта '\0'.
в данном посте я даже поиском ни разу не увидел вызов strlen

Обычно передают указатель на начало массива и количество элементов в массиве. Это ожидание пользователя функции по умолчанию. Если это не так, то в комментарии нужно обязательно указывать костыли (а ещё лучше - избавляться от них)
Алексей1153 вне форума Ответить с цитированием
Старый 04.08.2023, 15:01   #20
iXNomad
Пользователь
 
Регистрация: 06.01.2021
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
в данном посте я даже поиском ни разу не увидел вызов strlen

Обычно передают указатель на начало массива и количество элементов в массиве. Это ожидание пользователя функции по умолчанию. Если это не так, то в комментарии нужно обязательно указывать костыли (а ещё лучше - избавляться от них)
Ща распишу.

Было две задачи, я их немного спутал, потому что они обе были сложные, и в обеих у меня была идея с двумя указателями - то есть они работают в паре, в общем случае один указатель стоит в начале слова, пока второй бежит до первого пробела. Фишка в том, что если много пробелов, то они все сохраняются на своих местах, т.к. после того, как нужные действия со словом выполнены, указатель продолжает бежать до первого непробельного символа, и тот, который фиксировал начало предыдущего слова, двигается к тому, который бежит по словам, и начинает указывать на начало уже следующего слова.

В одной нужно было инвертировать все слова, но порядок оставить таким же, а в другой - инвертировать сам порядок слов, при этом слова в прямом порядке.

Я скинул решение второй.

"This is a sentence 3 spaces" -> "spaces 3 sentence a is This"

В самой этой задаче было условие - она принимает указатель на строку, длину строки (в значащих символах, без \0, то есть как strlen) и указатель на ещё одну пока пустую строку reversed, в которую я должен записать перевёрнутый порядок слов.
Я выкрутился так - сначала просто инвертирую строку, а потом пробегаюсь, определяю границы слов по пробелам и инвертирую каждое слово обратно. Получается, что сами слова написаны правильно, но в обратном порядке. Вообще написана сигнатура довольно странно, для меня это выглядит так, будто бы итоговая строка появляется аж в двух местах памятина итоговую строку указывают сразу два разных указателя reversed и reversed_words.

Первая же задача была немного другой - там нужно было просто инвертировать каждое слово, при этом порядок слов оставить таким же.

"This is a sentence 3 spaces" -> "sihT si a ecnetnes 3 secaps"

Код:
#include <stdlib.h>
#include <string.h>

char* reverseWords(const char* text) {
  char *s = malloc(strlen(text) + 1);
  strcpy(s, text);
  char *p0 = s;
  char *p1 = s;
  while(*p1 != '\0') {
    if(*p1 != ' ') {
      p0 = p1;
      while(*p1 != ' ' && *p1 != '\0') p1++;
      for(int i = 0; i < (p1 - p0) / 2; i++) {
        char tmp = *(p1 - 1 - i);
        *(p1 - 1 - i) = *(p0 + i);
        *(p0 + i) = tmp;
      }
    } else {
      p1++;
    }
  }
  return s;
}

Последний раз редактировалось iXNomad; 04.08.2023 в 15:13.
iXNomad вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
МГУ или куда идти дальше...(после колледжа) Алексей_2012 Свободное общение 9 20.01.2014 16:12
куда идти дальше после базового курса ? Gradus Свободное общение 4 28.01.2012 10:41
Какую купить версию книги Стивена Прата. Запутался. spamer Свободное общение 0 26.01.2010 03:01
Почему после выполнения do-while, вложенного в if, инструкции дальше не выполняются? Chewing_dog Помощь студентам 3 09.06.2009 06:44
После ошибки продолжить работу дальше Shouldercannon Общие вопросы Delphi 2 21.04.2009 11:23