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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 22.08.2013, 23:01   #21
Igor95
Форумчанин
 
Регистрация: 03.01.2013
Сообщений: 388
По умолчанию

Ну,я же не знаю выделяли ли под них память в какой-нибудь подпрограмме. Предположил, что выделяли.
Моя идея такая:
Код:
for (int i = 0; i < COUNT; i++)
{
node[i].next[i] = nullptr; // память под *next, как я понял, Вы не выделяли
}
for (int i = 0; i < COUNT; i++)
{
if (node[i].next != nullptr)
{
free(node[i].next);
node[i].next = nullptr;
}
else
{
break;
}
}
free(node);
node = nullptr;
P.S: Писал прямо здесь, не в IDE.
Возможно где-то ошибся.

Последний раз редактировалось Igor95; 22.08.2013 в 23:09.
Igor95 вне форума Ответить с цитированием
Старый 22.08.2013, 23:13   #22
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Цитата:
Опишите, пожалуйста, словами, как Вы представляете работу функции поиска.
Тут одной функцией не обойдёшся, а чтобы делать остальные нужно разобраться с возникшей проблемой, иначе нет смысла продолжать.
Цитата:
Единственное, нет гарантии, что в массиве node[COUNT] все поля next имеют значение NULL
Ну так все поля в NULL поставить не так важно по тому что сейчас все поля гарантированно не NULL. Можно эту проверку опустить.
do not use your brain
Кащей вне форума Ответить с цитированием
Старый 23.08.2013, 00:09   #23
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Как можно разобраться с проблемой, когда, например, я вообще не понимаю, как Вы представляете работу функции traversal, поэтому не могу предложить путей исправления.
На данный момент предлагается к рассмотрению такой код:
Код:
#define COUNT 4

typedef unsigned char byte;

struct Node
{
    byte n;
    struct Node** next;
};

struct Node*
traversal(byte data, struct Node* node)
{
    if (node == NULL || node->n == data)
        return node;
    int i = 0;
    while (node->next[i] != NULL && node->next[i]->n != data && ++i);
    return node->next[i];
}

int
main(void)
{
    struct Node node[COUNT];
    struct Node* t_node;
    int i, j;

    for (i = 0; i < COUNT; ++i) {
        node[i].n = (i + 1) * 10;
        node[i].next = malloc(sizeof(struct Node*) * COUNT);
        node[i].next[COUNT - 1] = NULL;
        for (j = 0; j < COUNT - 1; ++j)
            node[i].next[j] = &node[(i + j + 1) % COUNT];
    }

    t_node = traversal(21, node);
    if (t_node != NULL)
        printf("%d\n", t_node->n);
    else
        printf("NULL\n");

    for (i = 0; i < COUNT; ++i) {
        free(node[i].next);
        node[i].next = NULL;
    }

    return 0;
}
Тут нет ошибки изменения указателя next у самого элемента Node[0]. При этом, наличие такой "таблицы ссылок" у каждого элемента не имеет никакого смысла, так как поиск осуществляется по ссылкам из 0 элемента.

Насчет использования nullptr - код пишется под Си или С++?
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 23.08.2013, 10:25   #24
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Цитата:
Как можно разобраться с проблемой, когда, например, я вообще не понимаю, как Вы представляете работу функции traversal, поэтому не могу предложить путей исправления.
Что тут непонятного...есть массив указателей в структуре, который в цикле обходится функцией trawersal, она возвращает адрес структуры с искомым значением(параметр data) если он найден или NULL если доходит до последней ссылки в массиве(саму ссылку).
Это пока всё, тут незачем рассматривать программу целиком, так как вся суть представленного кода в применении функции traversal.
Цитата:
При этом, наличие такой "таблицы ссылок" у каждого элемента не имеет никакого смысла, так как поиск осуществляется по ссылкам из 0 элемента.
Наличие ссылок в остальных элементах имеет значение для будущих функций, которые ещё не написаны из за неустранённых ошибок.
Цитата:
Насчет использования nullptr - код пишется под Си или С++?
Си
do not use your brain
Кащей вне форума Ответить с цитированием
Старый 23.08.2013, 11:17   #25
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,577
По умолчанию

Цитата:
Си
забудь о nullptr )

Цитата:
Что тут непонятного...есть массив указателей в структуре, который в цикле обходится функцией trawersal, она возвращает адрес структуры с искомым значением(параметр data) если он найден или NULL если доходит до последней ссылки в массиве(саму ссылку).
Каждый экземпляр Node хранит значение (byte n) и набор ссылок на другие такие же Node : (struct Node** next)." Такие же", значит, что каждый из них также хранит набор ссылок.
Все это смахивает на n-арное дерево, и выглядит нормально.

Но как мне добраться до тех узлов, что расположены ниже первого яруса? - твоя функция traversal выглядит вкорне неверно, в этом случае - она должна быть рекурсивной, а у тебя " массив указателей в структуре, который в цикле обходится..."

Если ты не лезешь дальше первого яруса - я не понимаю нахрена тебе набор укзателей именно на Node и какой выхлоп может получиться с того что ты делаешь (я читал пост, где ты отвечал на этот вопрос, но в коде не вижу ничего похожего).

Мне чето лень разбирать что тут за код тебе постят BDA и Igor95 (они тоже ИМХО не понимают чего ты хочешь добиться), поэтому смотрю в код с первого поста:
Цитата:
Код:
while(*node -> next++ != NULL && (*node -> next) -> n != data);
	return **node -> next;
Прикинь, до цикла node->next указывает на элемент перед NULL
выполняется это: *node -> next++
теперь* node->next равен NULL, но выполняется вторая часть условия (ведь с NULL сравнивалась копия *node -> next, созданная до инкремента).
во второй части условия ты выполняешь (*node -> next) -> n
а это уже тоже самое что NULL->n (и тут программа должна падать)

Ну и дальше такое же безобразие происходит.

Последний раз редактировалось rrrFer; 23.08.2013 в 11:22.
rrrFer вне форума Ответить с цитированием
Старый 23.08.2013, 12:01   #26
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Цитата:
Но как мне добраться до тех узлов, что расположены ниже первого яруса?
Цитата:
она должна быть рекурсивной
Вот как раз чтобы отказаться от рекурсии я и мудрю с функцией traversal, она какбы отвечает за выбор ветки в древе.
Цитата:
нахрена тебе набор укзателей именно на Node
По тому как я потом полезу дальше по остальным Nod-ам, незачем думать что раз я щас не лезу, то и потом не полезу.
Цитата:
какой выхлоп может получиться
Даже не знаю что сказать..думай на перспективу.
Например, мне не нужно давать номера структурам(дополнительный id), чтобы получить доступ к данным, связать их, вместо них я пользую указатели, а это экономит память.
Если я захочу смоделировать нейрон в сети, мне не нужно будет гулять по его статическим связям и хранить их в памяти, по тому как связи станут динамическими. Если это база данных, то ненужно дублировать объёмистые данные при записи, это заменяется связями. Можно применить подобную структуру для написания базы данных экспертной системы или семантической сети.
Цитата:
и тут программа должна падать
Но она не падает, по тому как у инкремента приоритет выше.
Это значит что сначала *node -> next++, потом *node -> next != NULL и если вдруг он не равен NULL выполняется сравнение (*node -> next) -> n != data
Я тут не прав, сравнение всёравно проходит и программа падала.
do not use your brain

Последний раз редактировалось Кащей; 23.08.2013 в 12:43.
Кащей вне форума Ответить с цитированием
Старый 23.08.2013, 12:10   #27
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Код:
traversal(byte data, struct Node* node)
{
    if (node == NULL || node->n == data)
        return node;
    int i = 0;
    while (node->next[i] != NULL && node->next[i]->n != data && ++i);
    return node->next[i];
}
Так я смогу сделать в любой момент. Меня интересует именно использование циклов без счётчиков, так как количество ссылок может быть больше диапазона значений переменной используемого типа.
Иначе скажу - ссылки без ограничений, вот что хочется воплотить.
do not use your brain
Кащей вне форума Ответить с цитированием
Старый 23.08.2013, 12:44   #28
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Пока остановился на этом
Код:
struct Node* traversal(byte data, struct Node* node){
	while(*node -> next && (*node -> next) -> n != data && *node -> next++);
	return *node -> next;
}
do not use your brain

Последний раз редактировалось Кащей; 23.08.2013 в 12:50.
Кащей вне форума Ответить с цитированием
Старый 23.08.2013, 12:53   #29
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Обсуждаем последний вариант - Вы изменяете сам указатель next, тем самым разрушая 0 элемент (второй раз поиск будет нельзя осуществить).
ПС Дописывайте свое последнее сообщение, а не пишите несколько подряд (можно заработать штраф).
Код:
struct Node*
traversal(byte data, struct Node* node)
{
    if (node == NULL || node->n == data)
        return node;
    if (node->next == NULL)
        return NULL;
    struct Node **t = node->next;
    while (*t != NULL && (*t)->n != data && ++t);
    return *t;
}
Насчет ссылок без ограничений - сама переменная-указатель имеет ограниченный размер (счетчик того же размера сможет "посчитать" больше элементов).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 23.08.2013 в 13:02.
BDA на форуме Ответить с цитированием
Старый 23.08.2013, 12:56   #30
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Итак...как обойти изменение указателя не используя цикл?(вставленный в коде функции main)
Код:

    .  .  .

int c;
struct Node* traversal(byte data, struct Node* node){
	while(*node -> next && (*node -> next) -> n != data && *node -> next++)c++;
	return *node -> next;
}
//----------------------------------------------------------------------

    .  .  .

//----------------------------------------------------------------------
int main(void){
	struct Node node[COUNT];
	struct Node* t_node = NULL;
	
	if(create_all(node) == 0)
		t_node = traversal(30, &node[0]);
		for(;c > 0 && *t_node -> next--; c--);

	    .  .  .
	
	return 0;
}
do not use your brain
Кащей вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
работа с указателями compiler90 Visual C++ 1 04.06.2012 18:52
Работа с указателями yaapelsinko Общие вопросы Delphi 3 15.02.2012 01:13
Работа с указателями Byurrer Общие вопросы C/C++ 8 02.04.2011 21:09
Работа с указателями stas135642 Общие вопросы C/C++ 2 21.11.2010 15:05
Работа с указателями Mango Помощь студентам 2 23.11.2008 10:33