I'm using C++ to implement FP-growth algorithm, but I get some errors when using vector. Here is my code:
typedef struct Node
{
FPData *fpData;
int childCount;
struct Node *parent;
vector<Node*> childs;
}FPNode;
FPNode* FPTree::NewNode(string data, int support)
{
FPNode *node = (FPNode*) malloc(sizeof(FPNode));
FPData *fpData = (FPData*) malloc(sizeof(FPData));
fpData -> data = data;
fpData -> support = support;
node -> fpData = fpData;
node -> childCount = 0;
node -> parent = NULL;
return node;
}
void FPTree::InsertFPPath(FPNode* root, list<FPData*> fpDatas)
{
if(fpDatas.size() <= 0)
{
return;
}
bool flag = true;
for(int i = 0; i < root -> childCount; i++)
{
FPNode* child = root -> childs[i];
if(child -> fpData -> data == fpDatas.front() -> data)
{
flag = false;
child -> fpData -> support ++;
fpDatas.pop_front();
InsertFPPath(child, fpDatas);
break;
}
}
if(flag)
{
FPData* firstData = fpDatas.front();
FPNode* newChild = NewNode(firstData -> data, firstData -> support);
root -> childs.push_back(newChild); // error at here
root -> childCount ++;
fpDatas.pop_front();
for(int i = 0; i < fpDatas.size(); i++)
{
InsertFPPath(newChild, fpDatas);
}
}
}
The InsertFPPath() is a recursive method, I get error when second iterate:
root -> childs.push_back(newChild)
The error comes at:
construct(_Up* __p, _Args&&... __args) // here the __p is null, and __args is right
{
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
}
And the thread Queue stop at:
#0 0x00000001000050cf in void std::__1::allocator::construct(Node**, Node* const&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1673
the backtrace is :
#0 0x00000001000050cf in void std::__1::allocator::construct(Node**, Node* const&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1673
#1 0x00000001000050bc in void std::__1::allocator_traits >::__construct(std::__1::integral_constant, std::__1::allocator&, Node**, Node* const&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1600
#2 0x000000010000509c in void std::__1::allocator_traits >::construct(std::__1::allocator&, Node**, Node* const&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1453
#3 0x0000000100005079 in std::__1::vector >::push_back(Node* const&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1590
#4 0x0000000100004fa9 in FPTree::InsertFPPath(Node*, std::__1::list >) at /Users/dorothy/ME/USTC/作业/数据挖掘/experiment/FPTree/FPTree/FPTree.cpp:129
#5 0x00000001000051b4 in FPTree::InsertFPPath(Node*, std::__1::list >) at /Users/dorothy/ME/USTC/作业/数据挖掘/experiment/FPTree/FPTree/FPTree.cpp:135**
When you allocate memory for structures (struct or class) containing constructors, or for structures containing objects that have constructors, then you can't allocate the memory using malloc. The malloc function only allocates memory, but it doesn't call the constructors, and in your case that means that the childs member object will not be constructed and using the vector will lead to undefined behavior.
When allocating memory dynamically in C++ you need to use the new operator:
FPNode *node = new FPNode;
FPData *fpData = new FPData;
Related
I am almost done writing a bunch of functions for a linked list class I created but for some reason I have one memory leak that stems from the append->insert_back->insert function. Attached is the code for each:
append:
void LinkedList<T>::append(const LinkedList<T> &l2)
{
if (l2.isEmpty())
{
return;
}
//Set current position to l2 head
LLNode<T> *curr = l2.m_head;
//For as long as curr->next is not NULL insert to the back of this list the l2 list values
for(curr; curr->m_next != NULL; curr = curr->m_next){
insert_back(curr->m_data);
}
}
insert back:
void LinkedList<T>::insert_back(const T &x)
{
if (isEmpty())
{
//If the list is empty then use alternative method to store data in back
LLNode<T> *tmp = m_head;
while (tmp->m_next != NULL)
{
tmp = tmp->m_next;
}
insert(x, tmp);
}
else
{
insert(x, getAtPtr(m_size));
}
}
insert:
void LinkedList<T>::insert(const T &x, LLNode<T> *pos)
{
//Create tmp node to store position, set current position data to be passed in x, sets next position to be tmp
//variable.
LLNode<T> *tmp = new LLNode<T>;
*tmp = *pos;
pos->m_data = x;
pos->m_next = tmp;
m_size++;
}
and here is the exact memory link error message from valgrind:
void LinkedList<T>::insert(const T &x, LLNode<T> *pos)
{
==21462== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==21462== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21462== by 0x10C4A0: LinkedList<int>::insert(int const&, LLNode<int>*) (in /home/laner107/CS1575/Homework/Homework 2/Homework2/tester.ex)
==21462== by 0x10BACB: LinkedList<int>::insert_back(int const&) (in /home/laner107/CS1575/Homework/Homework 2/Homework2/tester.ex)
==21462== by 0x10C1E4: LinkedList<int>::append(LinkedList<int> const&) (in /home/laner107/CS1575/Homework/Homework 2/Homework2/tester.ex)
==21462== by 0x10AD81: test05() (in /home/laner107/CS1575/Homework/Homework 2/Homework2/tester.ex)
==21462== by 0x10B46E: main (in /home/laner107/CS1575/Homework/Homework 2/Homework2/tester.ex)
where is this memory link occurring at? Thank you in advance!
You are allocating an LLNode<T> and assigning it to tmp. Then tmp is assigned to pos. What happened to newly allocated LLNode<T>? It is leaked.
Just beginning with C++ (be gentle, please). I have some code and I have to:
Add Element* to make doubly-linked list
Add insert_before() and insert_after() methods to Element
Traverse list both ways with two separate for-loops
Print operating number inside each loop
Code
I tried the following:
#include <cstdio>
struct Element {
Element* next{};
Element* previous{};
void insert_after(Element* new_element) {
new_element -> previous = this;
new_element -> next = this -> next;
this -> next = new_element;
}
void insert_before(Element* new_element) {
new_element -> previous = this -> previous;
new_element -> next = this;
this -> previous = new_element;
}
char prefix[2];
short operating_number;
};
int main() {
Element trooper1, trooper2, trooper3, trooper4;
trooper1.prefix[0] = 'T';
trooper1.prefix[1] = 'K';
trooper1.operating_number = 421;
trooper1.insert_after(&trooper2);
trooper2.prefix[0] = 'F';
trooper2.prefix[1] = 'N';
trooper2.operating_number = 2187;
trooper2.insert_before(&trooper3);
trooper3.prefix[0] = 'L';
trooper3.prefix[1] = 'S';
trooper3.operating_number = 005;
trooper3.insert_before(&trooper4);
trooper4.prefix[0] = 'F';
trooper4.prefix[1] = 'K';
trooper4.operating_number = 2602;
for (Element *cursor = &trooper1; cursor; cursor = cursor -> next) {
printf("stormtrooper %c%c-%d\n",
cursor->prefix[0],
cursor->prefix[1],
cursor->operating_number);
}
for (Element *cursor = &trooper3; cursor; cursor = cursor -> previous) {
printf("stormtrooper %c%c-%d\n",
cursor->prefix[0],
cursor->prefix[1],
cursor->operating_number);
}
}
It's very basic, I know. But I'm starting to learn.
The code compiles correctly but I get this output:
/home/facundo/Escritorio/C++Projects/cmake-build-debug/C__Projects
stormtrooper TK-421
stormtrooper FN-2187
stormtrooper LS-5
stormtrooper FK-2602
stormtrooper TK-421
Process finished with exit code 0
I really don't understand why it prints only that (I guess there should be 8 lines of output).
I was expecting an output that would print the elements like this:
trooper1
trooper4
trooper3
trooper2
trooper2
trooper3
trooper4
trooper1
Some help would be really appreciated. Thanks for taking your time.
In your insert functions, you are not linking up all the pointers correctly:
void insert_after(Element* new_element) {
new_element -> previous = this;
new_element -> next = this -> next;
this -> next = new_element;
if (new_element -> next) // this check needed
// to correctly link the next -> previous
new_element -> next -> previous = new_element;
}
and
void insert_before(Element* new_element) {
new_element -> previous = this -> previous;
new_element -> next = this;
this -> previous = new_element;
if (new_element -> previous) // this check needed
// to correctly link the previous -> next
new_element -> previous -> next = new_element;
}
Also, in the second for loop, note that trooper2 is the last Element in the list, not trooper3, so you need to start from there to see all the Elements in reverse.
Here's a demo.
I'm having trouble with an assignment of mine. I've been going over the code for over a day, yet still can't seem to fix the issue. I've tried gdb, identified where the problem was and everything, so i'd really appreciate some fresh, more experienced eyes on this.
I don't know if I need to include the entire program so i'll just start with the issue at hand.
template <class TL>
void dlist<TL>::insert_after(iterate iter, TL &item){
Dnode<TL> *inserta = new Dnode<TL>;
if(iter.current -> next() == NULL){
iter.current -> set_next(inserta);
inserta -> set_previous(iter.current);
//inserta -> set_next(NULL);
inserta -> set_data(item);
tail = inserta;
}
//else if(iter.current == head || iter.current == tail)
// rear_insert(item);
else {
inserta ->set_next(iter.current -> next());
inserta -> set_previous(iter.current);
inserta -> set_data(item);
iter.current -> next() -> set_previous(inserta);
iter.current -> set_next(inserta);
}
++used;
}
This function uses an iterator to get the current node position, and inserts a new node and data in the position after. When I compile my project I get a Seg Fault 11, and using the GDB run command, my code stops here
Program received signal SIGSEGV, Segmentation fault.
Dnode<Swatch>::next (this=0x0) at ./dnode.h:14
14 Dnode *next(){return nextptr;}
Stepping through it leads me here,
(gdb) s
main () at main2.cc:56
56 for(int i = 0;i < swatches.size()/2;i++)
(gdb) s
58 if(swatches.size()%2 == 1){
(gdb) s
62 swatches.insert_after(it,tmp);
(gdb) s
which leads me to believe the insert_after function is my problem. Also, here is my dnode class:
#ifndef DNODE_H
#define DNODE_H
template <class TL>
class Dnode{
public:
typedef TL value;
Dnode(const TL &item = TL(), Dnode *init_next = NULL, Dnode *init_prev = NULL)
{data1 = item; nextptr = init_next; previousptr = init_prev;}
TL &data(){return data1;}
Dnode *previous(){return previousptr;}
Dnode *next(){return nextptr;}
const Dnode *previous()const{return previousptr;}
const Dnode * next()const {return nextptr;}
void set_data(const TL &newData){data1 = newData;}
void set_previous(Dnode *newPrev){previousptr = newPrev;}
void set_next(Dnode *newNext){nextptr = newNext;}
private:
TL data1;
Dnode *nextptr, *previousptr;
};
#endif
So, if anybody can help me out i'd appreciate it. And if I need to include more, I will.
Thanks
I have the following function
static node_ptr make_node_ptr()
{
return node_ptr(new node());
}
where using node_ptr = std::shared_ptr<node>;
I tried to find my segmentation fault with valgrind and gdb. In both I get more or less the same stack trace.
Program received signal SIGSEGV, Segmentation fault.
0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
(gdb) bt
#0 0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
#1 0x00007fff8f5d7877 in malloc_zone_malloc () from /usr/lib/system/libsystem_malloc.dylib
#2 0x00007fff8f5d6395 in malloc () from /usr/lib/system/libsystem_malloc.dylib
#3 0x00000001000f17d8 in operator new(unsigned long) () from /usr/local/lib/gcc/4.9/libstdc++.6.dylib
#4 0x0000000100009c04 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<msc::scene_manager<float, int, 3ul>::node*> (this=0x7fff5f4002e8, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:569
#5 0x0000000100008c78 in std::__shared_ptr<msc::scene_manager<float, int, 3ul>::node, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:871
#6 0x00000001000079e5 in std::shared_ptr<msc::scene_manager<float, int, 3ul>::node>::shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr.h:113
#7 0x0000000100005bdc in msc::scene_manager<float, int, 3ul>::make_node_ptr () at ../../common/msc/scene.d/scene_manager_def.h:98
#8 0x00000001000037dd in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (wrappee=...) at ../../common/msc/scene.d/node_impl.h:73
#9 0x0000000100003d53 in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (nodes=...) at ../../common/msc/scene.d/node_impl.h:112
#10 0x0000000100004011 in msc::scene_manager<float, int, 3ul>::insert (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:97
#11 0x0000000100006071 in msc::scene_manager<float, int, 3ul>::insert_if_leq (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:127
The last 2 lines repeat endlessly, I guess at least, as I tried to continue until frame #6000 or smth.
Am I missing something or is the creation of this shared_ptr not allowed?
Edit
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
{
bool swapped = false;
if (root == nullptr)
root = other;
else
{
auto inside = msc::inside::test(*root, *other);
if (inside == msc::inside::NONE)
{
auto oldRoot = root;
root = node::generate_wrapping_node(
std::vector<node_c_ptr>{ oldRoot, other });
insert_if_leq(root, oldRoot);
}
else if ((swapped = (inside == msc::inside::FIRST)))
{
std::swap(root, other);
}
other = insert_if_leq(root, other);
}
return !swapped ? other : root;
}
node_ptr scene_manager::insert_if_leq(node_ptr root, node_ptr other)
{
node_ptr res = root;
if (are_similar(*root, *other))
msc::move_append(root->children, other->children);
else
{
auto idx = root->get_quadrant_idx(other->center);
res = insert(root->quadrants[idx], other);
}
return res;
}
These are the functions which repeat. msc is my own namespace.
As the functions are recursive insert calls insert_if_leq and vice versa, I had to make node_ptr root in insert_if_leq a reference, because the assignment in insert depended on it. The new function definitions are as follows:
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
node_ptr scene_manager::insert_if_leq(node_ptr & root, node_ptr other)
I have a problem w ith linked lists in c++.
I have class looking like that:
class list {
private: struct node {
node * next;
int val;
};
node * head;
node * current;
public: list();
list(const list & l);
list & operator = (const list & l);~list();
void insert(int a);
void goToHead();
int getCurrentData();
void advance();
bool moreData();
};
I wont describe all functions in here, i'm sure they are working properly however there is declaration of operator = :
list & list::operator = (const list & l) {
if ( & l == this) return *this;
current = NULL;
node * src, * * dst;
head = ( * this).head;
src = l.head;
dst = & head;
while (src) {
if (!( * dst)) { * dst = new node;
}
( * dst) - > val = src - > val;
if (src == l.current) current = * dst;
src = src - > next;
dst = & (( * dst) - > next);
}
while (( * dst) != NULL) {
node * t = ( * dst) - > next;
delete * dst;
( * dst) = t;
}
return *this;
}
It has to copy values from one list to the other, add nodes or delete them if necessary.It works if lists are equal or if second one is longer( so it has to delete nodes).However when it should add some nodes then :
==4582== Conditional jump or move depends on uninitialised value(s)
==4582== at 0x8048C52: list::operator=(list const&) (list.cpp:103)
==4582== by 0x804891B: main (testlist.cpp:38)
==4582== Uninitialised value was created by a heap allocation
==4582== at 0x402B9B4: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4582== by 0x8048BDE: list::operator=(list const&) (list.cpp:93)
==4582== by 0x804891B: main (testlist.cpp:38)
I have no idea what is wrong with this declaration.Thanks for help.
Sorry if format was wrong, I'm having some chrome issues and that was the reason. Maybe there are examples however I have to use this one, I had a task to do it this way, I mean I had code example and just had to finish it. I still have same problem :
line 93 is :
* dst = new node;
And 103 is just last closing bracket
}
Again thanks for help.
Please format your code and mark line 93 and 103
If line 93 is
*dst=new node;
and 103
node *t=(*dst)->next;
you may want to sent dst->next to NULL (after you make the new) otherwise it points to uninitialized memory.