powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Анализ исходного кода. Разбор IOCCC 1985 august
25 сообщений из 281, страница 4 из 12
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786235
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryВот мой код

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//конструктор пространства макроопределений
struct MacroSpace* create_MacroSpace()
{
	struct MacroSpace*	ms = (struct MacroSpace*)malloc(sizeof(struct MacroSpace));
	ms->count = 0;
	return ms;
}


Ну, и кто будет ms->m инициализировать? Там по-прежнему мусор :)
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786236
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskySashaMercuryВот мой код

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//конструктор пространства макроопределений
struct MacroSpace* create_MacroSpace()
{
	struct MacroSpace*	ms = (struct MacroSpace*)malloc(sizeof(struct MacroSpace));
	ms->count = 0;
	return ms;
}


Ну, и кто будет ms->m инициализировать? Там по-прежнему мусор :)

Саша балда. Извините, глупая ошибка : (
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786276
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На ваш взгляд, такая функция имеет место быть в данной программе ?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
//установка стартового значения макроопределения
int setstartvalue_Macro(struct Macro* m)
{
	m->type = 0;
	m->count_args = 0;
	m->identifier = NULL;
	m->list_args = NULL;
	m->rep_list = NULL;
	return 0;
}



Сделал вывод: Для любой структуры данных (особенно если в ней присутствуют объекты на которые в дальнейшем планируется выделять память) нужно писать отдельный конструктор.

Этот вывод правильный ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786306
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЭтот вывод правильный ?правильный, в целом, и ведёт он к отказу от С и переходу к С++ )))
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786544
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСделал вывод: Для любой структуры данных (особенно если в ней присутствуют объекты на которые в дальнейшем планируется выделять память) нужно писать отдельный конструктор.

Этот вывод правильный ?
В одной из серий мульт-сериала Симпсоны, Нельсон бросает камень в белку.
Белка убегает. Нельсон записывает в блокнотик вывод - "Белки не любят камни".
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786654
Владимир2012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryВчера я решил заняться чем-нибудь интересным
http://cpip.sourceforge.net/
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786686
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо что этот вывод правильный :) Изучения языка, подобно пониманию окружающего мира ребенком, потому даже такой вывод кажется большим.

Часть программы написал около 5 часов назад, но мне не нравится эта функция, сначала переделаю а потом покажу :) Я нашёл отличную статью на выходные C:
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786858
Владимир2012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати пришлось и мне решать подобного рода вопросы.
http://rsdn.ru/forum/com/5693941 MSDN wrapper classes

Так вот при генерации кода для *.idl была проблема поместить перед определениями
интерфейсов все необходимые "нестандартные" определения структур, ... /UDT/.
Так вот алгоритм находил в *.h Microsoft определение какого-либо "нестандартного" типа
/не забываем о том, что automation выставляет свои правила использования типов данных .../
и если к примеру это было определение какой-либо структуры, то нужно было пройтись по
определениям полей и если встречался "нестандартный" тип, то вытащить из *.h для него
определение ...
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38786942
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton"Белки не любят камни".что, в целом, недалеко от истины, тем не менее ;-))
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787406
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

обрати внимание на

Код: plaintext
1.
ms->m=(struct Macro*)realloc(ms->m, ms->count*sizeof(struct Macro));



задай себе вопрос: для ms->m я выделил память, чтобы ее переаллоцировать?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787779
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий ШироковSashaMercury,

обрати внимание на

Код: plaintext
1.
ms->m=(struct Macro*)realloc(ms->m, ms->count*sizeof(struct Macro));



задай себе вопрос: для ms->m я выделил память, чтобы ее переаллоцировать?

Нет, не выделял. А разве в спецификации realloc говорится о том, что нельзя реаллоцировать память, если память ещё не выделена, а указатель проинициализирован в NULL ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787780
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько я понял realloc перераспределяет память для блока, с новой длиной. Функция возвращает указатель на блок с новой длиной (поэтому адрес может не совпадать с тем, по которому происходит перераспределение памяти, потому присвоение обязательно, fe p=(T)realloc(p,size), нельзя просто realloc(p,size)). Исходя из того что я понимаю(и если я ничего не упустил в стандарте, сейчас проверю), достаточно того, чтобы указатель бы проинициализирован.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787781
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ISO/IEC 9899:201x7.22.3.5 The realloc function
Synopsis
1 #include <stdlib.h>
void *realloc(void *ptr, size_t size);
Description
2 The realloc function deallocates the old object pointed to by ptr and returns a
pointer to a new object that has the size specified by size. The contents of the new
object shall be the same as that of the old object prior to deallocation, up to the lesser of
the new and old sizes. Any bytes in the new object beyond the size of the old object have
indeterminate values.
3 Ifptr is a null pointer, the realloc function behaves like the malloc function for the
specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory
management function, or if the space has been deallocated by a call to the free or
realloc function, the behavior is undefined. If memory for the new object cannot be
allocated, the old object is not deallocated and its value is unchanged.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787783
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, скорее всего malloc частный случай realloc, и такое в Си встречается, пока не решил как к этому отношусь, хорошо или плохо. С одной стороны нужно помнить больше функций, происходит дублирование, увеличение общего объёма кода (при подключении библиотек), а с другой стороны скорее всего плюсы какие-то есть, просто я их не вижу в силу своей малой грамотности в теории языков программирования
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787790
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне кажется, что я ошибаюсь при работе с массивом указателей list_args.
Первым делом

Код: plaintext
1.
m->list_args = NULL;


Затем, добавлю в цикле аргументы, вот что происходит в цикле

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//i=0..
cur->list_args = (char**)realloc(cur->rep_list, (i + 1)*sizeof(char*));
cur->list_args[i] = NULL;

//smh do

cur->list_args[i] = (char*)malloc(sizeof(char)*len);



Подскажите пожалуйста, правильный ли порядок действий ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787791
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде бы всё понимаю, у меня есть массив указателей, сначала нужно установить в NULL его голову, затем в цикле реаллоцировать в зависимости от текущего количества строк, новую реаллоцированную строку нужно установить в NULL, и следующим действием выделить на неё столько памяти, сколько нужно. Но где-то у меня ошибка
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787794
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Почему у вас выделенное ниже - разные выражения?
Код: plaintext
1.
cur->list_args = (char**)realloc(cur->rep_list, (i + 1)*sizeof(char*));


После вызова realloc, cur->rep_list становится невалидным. И последующий вызов будет работать с мусором.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787795
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ааа..Не знаю почему я вообще так написал и не заметил, сейчас исправлю!
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787796
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, спасибо, заработало C :

Ну как я мог такое не проверить.. Уже все варианты продумал, прочитал статью про realloc, думал что неправильно работаю с памятью, а ошибка оказалась обычной опечаткой из-за неудачного именования полей структуры, и моей невнимательности (
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787806
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот такая функция получилась. 1 вариант. Она будет запускаться как только программа поиска встретит токен "#define"

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
#define MAX_LENGTH_INTERNAL_IDENTIFIER (63+1) //согласно стандарту ISO/IEC 9899:201x
#define MAX_LENGTH_REP_LIST (1000+1) //по собственным соображениям
#define MASK "%[a-z A-Z _ 0-9]" //множество сканирования для инициализации макроимени и параметров
#define MASK2 "%[^\n]"

//Добавление макроопределиния к пространству макросов
int add_macros(struct MacroSpace* ms, FILE* in)
{
	//1. Работа с памятью 
	ms->count += 1;
	ms->m = (struct Macro*)realloc(ms->m, ms->count*sizeof(struct Macro));
	struct Macro* cur = &(ms->m[ms->count - 1]);//указатель на текущий макрос, создал его чтобы было проще работать в дальнейшем
	setstartvalue_Macro(cur);//инициализация всех элементов текущей(вновь созданной) структуры макроопределения стартовыми значениями

	//2. Инициализация макроопределния

	//иниициализация идентификатора cur->identifier
	char* temp = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
	fscanf(in, MASK, temp);
	char* temp2 = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
	sscanf(temp, "%s", temp2);
	int len = strlen(temp2) + 1;
	cur->identifier = (char*)malloc(sizeof(char)*len);
	strcpy(cur->identifier, temp2);
	free(temp);
	free(temp2);

	//инициализация типа макроимени и массива аргументов cur->list_args
	int next_char;
	fscanf(in, "%c", &next_char);
	if ((char)next_char == '(')
	{
		cur->type = 1;//меняю тип макроимени
		//инициализация массива аргументов
		int i = 0;
		while ((char)next_char != ')')
		{
			cur->list_args = (char**)realloc(cur->list_args, (i + 1)*sizeof(char*));
			cur->list_args[i] = NULL;


			char* temp = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
			fscanf(in, MASK, temp);
			char* temp2 = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
			sscanf(temp, "%s", temp2);
			int len = strlen(temp2) + 1;
			cur->list_args[i] = (char*)malloc(sizeof(char)*len);
			strcpy(cur->list_args[i], temp2);
			free(temp);
			free(temp2);

			cur->count_args += 1;
			//printf("%s\n", cur->list_args[i]);
			fscanf(in, "%c", &next_char);
			i += 1;
		}
	}

	//инициализация  cur->repl_list
	temp = (char*)malloc(sizeof(char)*MAX_LENGTH_REP_LIST);
	fscanf(in, MASK2, temp);
	len = strlen(temp) + 1;
	cur->rep_list = (char*)malloc(sizeof(char)*len);
	strcpy(cur->rep_list, temp);
	free(temp);

	return 0;
}



Конечно, часть функции касаемо записи в идентификаторы имени макроподстановки и её параметров лучше бы вынести в отдельную функцию, что я и пытался сделать, но неудачно. Если использовать такую подфункцию то ничего не происходит

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
//Установка значения идентефикатора из потока на входе
int set_identifier(FILE* in, char* destination)
{
	char* temp = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
	fscanf(in, MASK, temp);
	char* temp2 = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
	sscanf(temp, "%s", temp2);
	int len = strlen(temp2) + 1;
	destination = (char*)malloc(sizeof(char)*len);
	strcpy(destination, temp2);
	free(temp);
	free(temp2);
	return 0;
}



Подумаю почему.

Ну и скорее всего придётся передать эту функцию с точки зрения логики, мне кажется я получаю нужные строки далеко не оптимально. Вы согласны ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38787843
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет. Реализация плохая.
А могу ли я считать по маске "%[a-zA-Z_]%[0-9]" в один массив ?

Подумал, если встречаю токен "#define" то считывать сразу всю строку до '\n' и с ней уже работать. Пока что общий алгоритм поиска выглядит так


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
//Устанавливает позицию  индикатора файла на первый символ новой строки. Возвращает 1 если всё ок.
//Если файл закончился (новой строки нет), возвращает -1
int step_to_newline(FILE* in)
{
	int c;
	while ((c = getc(in)) != '\n')
	{
		if (c == EOF) return -1;
	}
	return 1;
}
//как бы лучше назвать ?
int search_and_set__MacroSpace(FILE* in, struct MacroSpace* ms)
{
	do
	{
		char* w1 = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
		fscanf(in, "%s", w1);
		(strcmp(w1, "#define") == 0) ? add_macros(ms, in) : false;
	} 
	while (step_to_newline(in) != -1);
	return 0;
}
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788779
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте. Основные моменты решил. У меня остался один вопрос, подскажите пожалуйста. У нас есть такой участок кода.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#define MASK "%[a-zA-Z_0-9]%" //множество сканирования для инициализации макроимени и параметров
              //. . . . .
	char* temp = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
	fscanf(in, MASK, temp);
	int len = strlen(temp) + 1;
	cur->identifier = (char*)malloc(sizeof(char)*len);
	strcpy(cur->identifier, temp);
	free(temp);

	//инициализация типа макроимени и массива аргументов cur->list_args
	int next_char = fgetc(in);



Допустим индикатор положения файла указывает на q, то есть в temp запишется q. Как будет проинициализирован next_char ?(между q и struct есть пробел)

#define q struct b
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788780
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня постоянно инициализируется s, сколько бы пробелов не было между struct и q. А если выше я сделаю ungetc(' ',in), то всё хорошо
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788787
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как я понял, первое считывание по маске даёт такой эффект (установка указателя в файле после всех пробелов), хотя по этому примеру из стандарта, я этого не ожидал.

ISO/IEC 9899:201xEXAMPLE 2 The call:
#include <stdio.h>
Код: plaintext
1.
2.
3.
/* ... */
int i; float x; char name[50];
fscanf(stdin, "%2d%f%*d %[0123456789]", &i, &x, name);

with input:
56789 0123 56a72
will assign to i the value 56 and to x the value 789.0, will skip 0123, and will assign to name the
sequence 56\0. The next character read from the input stream will be a.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788791
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если сделать считывание по маске вот таким, то всё заработало. А почему так, я не понял.

Код: plaintext
1.
fscanf(in, "%[^ (]", temp);
...
Рейтинг: 0 / 0
25 сообщений из 281, страница 4 из 12
Форумы / C++ [игнор отключен] [закрыт для гостей] / Анализ исходного кода. Разбор IOCCC 1985 august
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]