Zdravim,
1. pouzitie ukazovatelov
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int SIZE = 2;
struct foo
{
int n;
};
struct proxy
{
void * object;
};
typedef vector<foo> FooVector;
typedef vector<vector<proxy*>*> Tree;
typedef vector<proxy*> Leaf;
Tree ** tree;
foo getFoo(const proxy * p)
{
foo f = *((foo*)p->object);
return f;
}
void addToTree(int n, int index)
{
if (!tree[index])
tree[index] = new Tree;
foo * f = new foo;
f->n = n;
cout << f->n << endl;
Leaf * lPtr = new Leaf;
proxy * proxyPtr = new proxy;
proxyPtr->object = (void*)f;
lPtr->push_back(proxyPtr);
tree[index]->push_back(lPtr);
}
int main()
{
tree = new Tree*[SIZE];
memset(tree, 0, SIZE * sizeof(Tree*));
addToTree(10, 0);
addToTree(11, 1);
addToTree(12, 0);
for (int i = 0; i < SIZE; i++)
{
if (tree[i])
{
for (Tree::iterator t_it = tree[i]->begin(); t_it != tree[i]->end(); t_it++)
{
for (Leaf::iterator l_it = (*t_it)->begin(); l_it != (*t_it)->end(); l_it++)
{
cout << getFoo(*l_it).n << endl;
delete (foo*)((*l_it)->object);
delete *l_it;
}
delete *t_it;
}
}
delete tree[i];
}
delete [] tree;
return 0;
}
vystup
10
11
12
10
12
11
vystup valgrindu:
$ valgrind ./tree_ptr
==7993== Memcheck, a memory error detector
==7993== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==7993== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==7993== Command: ./tree_ptr
==7993==
10
11
12
10
12
11
==7993==
==7993== HEAP SUMMARY:
==7993== in use at exit: 0 bytes in 0 blocks
==7993== total heap usage: 18 allocs, 18 frees, 228 bytes allocated
==7993==
==7993== All heap blocks were freed -- no leaks are possible
==7993==
==7993== For counts of detected and suppressed errors, rerun with: -v
==7993== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
vsetko funguje presne tak ako ma
2. pouzitie ukazovatelov na iteratory
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int SIZE = 2;
struct foo
{
int n;
};
struct proxy
{
void * object;
};
typedef vector<foo> FooVector;
typedef vector<vector<proxy*>*> Tree;
typedef vector<proxy*> Leaf;
FooVector fooVector;
Tree ** tree;
foo getFoo(const proxy * p)
{
FooVector::iterator * itPtr = (FooVector::iterator*)p->object;
foo f = *(*itPtr);
return f;
}
void addToTree(int n, int index)
{
if (!tree[index])
tree[index] = new Tree;
foo f;
f.n = n;
fooVector.push_back(f);
FooVector::iterator * itPtr = new FooVector::iterator;
(*itPtr) = fooVector.end();
(*itPtr)--;
cout << (*itPtr)->n << endl;
Leaf * lPtr = new Leaf;
proxy * proxyPtr = new proxy;
proxyPtr->object = (void*)itPtr;
lPtr->push_back(proxyPtr);
tree[index]->push_back(lPtr);
}
int main()
{
tree = new Tree*[SIZE];
memset(tree, 0, SIZE * sizeof(Tree*));
addToTree(10, 0);
addToTree(11, 1);
addToTree(12, 0);
for (int i = 0; i < SIZE; i++)
{
if (tree[i])
{
for (Tree::iterator t_it = tree[i]->begin(); t_it != tree[i]->end(); t_it++)
{
for (Leaf::iterator l_it = (*t_it)->begin(); l_it != (*t_it)->end(); l_it++)
{
cout << getFoo(*l_it).n << endl;
delete (FooVector::iterator*)((*l_it)->object);
delete *l_it;
}
delete *t_it;
}
}
delete tree[i];
}
delete [] tree;
return 0;
}
vystup
10
11
12
21618996
12
0
vystup valgrindu:
$ valgrind ./tree_it
==8006== Memcheck, a memory error detector
==8006== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==8006== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==8006== Command: ./tree_it
==8006==
10
11
12
==8006== Invalid read of size 4
==8006== at 0x400C97: getFoo(proxy const*) (in /home/gman/tree_it)
==8006== by 0x400EFD: main (in /home/gman/tree_it)
==8006== Address 0x594d0f0 is 0 bytes inside a block of size 4 free'd
==8006== at 0x4C2658C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8006== by 0x4029FD: __gnu_cxx::new_allocator<foo>::deallocate(foo*, unsigned long) (in /home/gman/tree_it)
==8006== by 0x402265: std::_Vector_base<foo, std::allocator<foo> >::_M_deallocate(foo*, unsigned long) (in /home/gman/tree_it)
==8006== by 0x40196C: std::vector<foo, std::allocator<foo> >::_M_insert_aux(__gnu_cxx::__normal_iterator<foo*, std::vector<foo, std::allocator<foo> > >, foo const&) (in /home/gman/tree_it)
==8006== by 0x4011AD: std::vector<foo, std::allocator<foo> >::push_back(foo const&) (in /home/gman/tree_it)
==8006== by 0x400D10: addToTree(int, int) (in /home/gman/tree_it)
==8006== by 0x400E66: main (in /home/gman/tree_it)
==8006==
10
12
11
==8006==
==8006== HEAP SUMMARY:
==8006== in use at exit: 0 bytes in 0 blocks
==8006== total heap usage: 21 allocs, 21 frees, 268 bytes allocated
==8006==
==8006== All heap blocks were freed -- no leaks are possible
==8006==
==8006== For counts of detected and suppressed errors, rerun with: -v
==8006== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 4 from 4)
cize halvny rozdiel medzi 1 a 2 je ten, ze v prvom pripade vo funkcii addToTree alokujem pamat a vytvaram novy objekt typu foo, vytvorim proxy a do object priradim adresu vytvoreneho foo objektu. V druhom pripade mi pribudol vector<foo> fooVector. V addToTree si vytvorim objekt typu foo, vlozim ho do fooVector, alokujem pamat pre FooVector::iterator, priradim do nej iterator na konci fooVector kontajneru. A znova ako v 1 si vytvorim proxy ale tento raz si do object priradim adresu iteratora. Aspon mne pripada zeby vysledok mal byt rovnaky, ale ocividne nie je. Takze by som sa chcel spytat, ako rozchodit druhy zdrojak.
Diky moc za odpovede