Форум программистов, компьютерный форум CyberForum.ru

Не знаю как правильно передать указатель - C++

Восстановить пароль Регистрация
 
AncinetHero
49 / 49 / 3
Регистрация: 22.05.2011
Сообщений: 326
17.01.2013, 23:41     Не знаю как правильно передать указатель #1
В общем для начала приложу код ( не пугайтесь , что придется много читать , из этого кода изучить нужно лишь 2 функции и данные структуры ) :
C++
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
 
#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back 
#define mp make_pair
 
typedef long long ll ;
 
ifstream Cin( "input.txt" );
ofstream Cout( "output.txt" );
 
struct Treap
{
       ll x ; 
       ll y ;
       
       Treap *Left ;
       Treap *Right ;
       
       Treap () { } ;
       Treap ( ll x, ll y ) : x(x), y(y) { } ;
       Treap ( ll x, ll y, Treap *l, Treap *r ) : x(x), y(y), Left(l), Right(r) { }
};
 
typedef Treap * PTreap  ;
 
void Merge( PTreap & ans, PTreap l, PTreap r )
{
      
      if( l == NULL )
        ans = r ;
      if( r == NULL )
        ans = r ;
      
      if( l->y >= r->y )
      {
          Merge( l->Right, l->Right, r ) ;
          ans = l ;
      }
      else
      {
          Merge( r->Left, l, r->Left ) ;
          ans = r ; 
      }
}
 
void Split( PTreap & l, PTreap & r, ll x, PTreap g ) 
{
     if( !g )
       l = r = NULL ;
     else if( x < g->x )
     {
         Split( l, g->Left, x, g->Left ) ;
         r = g ;
     }
     else
     {
         Split( g->Right, r, x, g->Right ) ;
         l = g ;
     }
}
 
void insert( PTreap & g, ll x )
{
     PTreap l, r ;
     Split( l, r, x, g ) ;
     PTreap New = new Treap( x, rand(), NULL, NULL ) ;
     Merge( l, l, New ) ;
     Merge( g, l, r ) ;
}
 
main()
{ 
      ll n, i ;
      Treap a ;
      cin >> n ;
      vector < ll > r(n) ;
      FOR0( i, n )
      {
        cin >> r[i] ;
        insert( a, r[i] ) ;
      }
        
}
Я создал структуру Treap - дерево. Создал тип данных - указатель на эту структуру - PTreap = * Treap . У меня есть функция void insert( PTreap & g, ll x ) , которая принимает указатель на мое дерево и число, которое я хочу засунуть в дерево, оно его туда засовывает и обновляет переданый ему указатель. Я гарантирую, что работа всех функций, относящихся к дереву, правильна, и ошибок нету.
В главной процедуре main я должен создать дерево, считать некоторые данные и засунуть их в это дерево.
Я не очень разбираюсь в указателях и совершенно запутался, как нужно передать это дерево функции insert , чтобы не было ошибок. Текущий код не компилируется, не знаю как правильно передать указатель на дерево, причем с возможностью его менять...
Очень нуждаюсь в помощи, спасибо !
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zongo
1 / 1 / 0
Регистрация: 12.01.2013
Сообщений: 39
17.01.2013, 23:51     Не знаю как правильно передать указатель #2
Хоть лог ошибок приложил бы...
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11849 / 6828 / 773
Регистрация: 27.09.2012
Сообщений: 16,930
Записей в блоге: 2
Завершенные тесты: 1
18.01.2013, 00:02     Не знаю как правильно передать указатель #3

Не по теме:

Кто писал этот код?


C++
1
PTreap a ;
AncinetHero
49 / 49 / 3
Регистрация: 22.05.2011
Сообщений: 326
18.01.2013, 01:19  [ТС]     Не знаю как правильно передать указатель #4
Цитата Сообщение от Croessmah Посмотреть сообщение

Не по теме:

Кто писал этот код?


C++
1
PTreap a ;

Не по теме:

Писал я, а что не так ?



Спасибо, теперь ошибка в другом ! Дело в том, что программа вылетает с ошибкой как только программа доходит до момента:
C++
1
2
Ptreap x ;
if( !x ) ;
Взято отсюда:
C++
1
2
3
void Split( PTreap & l, PTreap & r, ll x, PTreap g ) 
{
     if( !g )
Именно, когда проверяется условие возникает ошибка ! Возможно у моей структуры не правильно определен 0, или что-то в этом роде..?
Croessmah
18.01.2013, 01:22
  #5

Не по теме:

Разбираться в данном коде почему происходит ошибка что-то не хочется из-за того, что данный код не читабелен совершенно. Только время убивать почем зря, имхо.

И зачем Вам свое дерево с таким набором заголовков?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>

AncinetHero
49 / 49 / 3
Регистрация: 22.05.2011
Сообщений: 326
18.01.2013, 01:26  [ТС]     Не знаю как правильно передать указатель #6

Не по теме:

А причем тут заголовки ? Ведь можно колесико вниз и они пропадут.. Это моя заготовка для решения олимпиадных задач по программированию. Этот код часть задачи. И почему нечитабелен код, обьясните пожалуйста!



Надеюсь, читаемость повысится:
C++
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
69
70
71
72
73
74
75
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
using namespace std;
 
struct Treap
{
       long long x ; 
       long long y ;
       
       Treap *Left ;
       Treap *Right ;
       
       Treap () { } ;
       Treap ( long long x, long long y ) : x(x), y(y) { } ;
       Treap ( long long x, long long y, Treap *l, Treap *r ) : x(x), y(y), Left(l), Right(r) { }
};
 
typedef Treap * PTreap  ;
 
void Merge( PTreap & ans, PTreap l, PTreap r )
{
      
      if( l == NULL )
        ans = r ;
      if( r == NULL )
        ans = r ;
      
      if( l->y >= r->y )
      {
          Merge( l->Right, l->Right, r ) ;
          ans = l ;
      }
      else
      {
          Merge( r->Left, l, r->Left ) ;
          ans = r ; 
      }
}
 
void Split( PTreap & l, PTreap & r, long long x, PTreap g ) 
{
     if( !g )
       l = r = NULL ;
     else if( x < g->x )
     {
         Split( l, g->Left, x, g->Left ) ;
         r = g ;
     }
     else
     {
         Split( g->Right, r, x, g->Right ) ;
         l = g ;
     }
}
 
void insert( PTreap & g, long long x )
{
     PTreap l, r ;
     Split( l, r, x, g ) ;
     PTreap New = new Treap( x, rand(), NULL, NULL ) ;
     Merge( l, l, New ) ;
     Merge( g, l, r ) ;
}
 
main()
{ 
      long long x ;
      PTreap a = new Treap ;
      
      cin >> x ;
      
      insert( a, x ) ;
}
Croessmah
18.01.2013, 01:34
  #7

Не по теме:

Цитата Сообщение от AncinetHero Посмотреть сообщение
И почему нечитабелен код, обьясните пожалуйста!
Этот код можете прочитать только Вы. Стороннему человеку понадобиться время, чтобы в нем разобраться...разобраться в том, что тут написано, не говоря уже о заложенной логике.
Забросьте этот код на пол года и потом попробуйте прочитать
Цитата Сообщение от AncinetHero Посмотреть сообщение
Причем тут заголовки ?
Смысл их подключать, если Вы их не используете?
Давайте писать свой вектор, при этом подключив <vector>
Цитата Сообщение от AncinetHero Посмотреть сообщение
Это моя заготовка для решения олимпиадных задач по программированию
Если только по теме "Учусь сокращать и шифровать код"

AncinetHero
49 / 49 / 3
Регистрация: 22.05.2011
Сообщений: 326
18.01.2013, 01:37  [ТС]     Не знаю как правильно передать указатель #8
Я вроде бы все ненужное удалил, функции называются удобно - по функции, которую они выполняют. Больше читаемость повысить невозможно !
FreeMinder
 Аватар для FreeMinder
36 / 36 / 2
Регистрация: 29.08.2012
Сообщений: 59
18.01.2013, 01:55     Не знаю как правильно передать указатель #9
Цитата Сообщение от AncinetHero Посмотреть сообщение
PTreap a = new Treap ;
У вас конструктор по умолчанию не инициализирует переменные. Объект создался, в x и y мусор, указатели left и right невалидны. В функциях разбираться желания нет, но проблема скорее всего в обращении к невалидным указателям, проверяйте их перед использованием.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.01.2013, 02:04     Не знаю как правильно передать указатель
Еще ссылки по теме:

как в функцию передать указатель на матрицу C++
C++ Не могу понять, как правильно передать указатель на объект в файл
C++ Не знаю как передать вектор в процедуру

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11849 / 6828 / 773
Регистрация: 27.09.2012
Сообщений: 16,930
Записей в блоге: 2
Завершенные тесты: 1
18.01.2013, 02:04     Не знаю как правильно передать указатель #10
В последнем приведенном коде ошибка возникает при вызове Split в функции insert
C++
1
Split( l, r, x, g ) ;
Происходит она по тому, что объект Treap создавался как
C++
1
PTreap a = new Treap;
Конструктор по умолчанию пуст и поля объекта содержат мусор.
Соответственно, в функции split условие
C++
1
if( !g )
не выполняется, и при выполнении одной из веток, например
C++
1
Split( l, g->Left, x, g->Left )
Left содержит мусор, который передается в функцию. Естевственно, условие снова не выполняется и при
C++
1
else if( x < g->x )
происходит ошибка, потому как
x<мусор->x

Не по теме:

Цитата Сообщение от AncinetHero Посмотреть сообщение
Больше читаемость повысить невозможно !
ну это сугубо Ваше мнение

Yandex
Объявления
18.01.2013, 02:04     Не знаю как правильно передать указатель
Ответ Создать тему

Метки
декартово дерево, указатели
Опции темы

Текущее время: 17:09. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru