Probably wrong use of dynamic memory allocation

Hi,
I once wanted to make something in code which would work the same as an array which doesn't need a predefined size, so I could add an infinite number of objects . (in other words, a kind of vector.) The code is a bit old, but it functioned. It was a linear list of objects, but the objects were added in the wrong order (the object which was added first would be the last object to be read) so I actually reversed the reading function so the objects would be read in the correct order. (but were saved in the wrong) As I said: it worked, but I thought the reversed reading-solution was a bad one, so I recently tried to fix this issue by making a new adding algorithm in which the objects would directly be added in the right order. My compiler doesn't complain about any errors, but as soon as I run the program, it crashes. I found out that the problem lies in the forgeLink(X info) function, if I comment it away the program runs normally, so focus on that function. Here is the source code:

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
#include<iostream>
template<class X>
struct Link
{
  X data;
  Link<X>*nextPtr;
  unsigned long long nmbr;
  Link(X info,Link<X>*oldLink,unsigned no);
};
template<class X>
Link<X>::Link(X info,Link<X>*oldLink,unsigned no):
  data(info),nextPtr(oldLink),nmbr(no)
{}
template<class X>
struct Chain
{
  Link<X>*startPtr;
  unsigned long long length;
  Chain();
  void forgeLink(X info);
  X breakLastLink();
  void writeChain(std::ostream&stream=std::cout);
  //void operator+=(Chain<X> chain,X array[]);
};
template<class X>
Chain<X>::Chain():
  startPtr(0),length(0)
{}
template<class X>
void Chain<X>::forgeLink(X info)
{
  Link<X>*Ptr=this->startPtr;
  for(;;)
  {
    if(Ptr->nextPtr!=0||Ptr!=0)
      Ptr=Ptr->nextPtr;
    else
    {
      Ptr->nextPtr=new Link<X>(info,0,this->length);
      this->length++;
      break;
    }
  }
}
template<class X>
X Chain<X>::breakLastLink()
{
  Link<X>*Ptr=this->startPtr;
  unsigned long long linkNo;
  for(;;)
  {
    if(Ptr->nextPtr!=0)
      Ptr=Ptr->nextPtr;
    else
      linkNo=Ptr->nmbr;
      break;
  }
  Ptr=this->startPtr;
  for(unsigned long long i=0;i<linkNo-1;i++)
  {
  	Ptr=Ptr->nextPtr;
  }
  delete Ptr->nextPtr;
  Ptr->nextPtr=0;
  this->length--;
}
template<class X>
void Chain<X>::writeChain(std::ostream&stream)
{
  Link<X>*chainItr=this->startPtr;
  for(unsigned long long i=0;i<this->length;i++)
  {
    stream<<chainItr->data<<'\n';
  }
}
/*template<class X>
void Chain<X>::operator+=(Chain<X> chain,X array[])
{
  for(unsigned long long i=0;i<sizeof(array);i++)
    this->forgeLink(array[i]);
}*/
int main()
{
  Chain<int> chain;
  chain.forgeLink(1);
  chain.forgeLink(2);
  chain.forgeLink(3);
  chain.writeChain();
  std::cin.get();
}

The comments in the code are a function which isn't finished yet, I was too lazy to remove them. And I found it useful to visualize the chain object by drawing it on a piece of paper, so I could maintain the positions of the various pointers.
Dynamic memory has always been my weak spot, so I guess it's an allocation issue. I'm also not completely sure if this topic doesn't belong to the beginners forum, but I'm not sure the people there are better experienced in dynamic allocation than I am, so I apologize if you think this topic doesn't belong here.
Comments on my way of coding or programming style are welcome too. Also, if something is unclear, don't be afraid of asking.

Kind regards,
Niels Meijer
Your program appears to be crashing in the following line:
if(Ptr->nextPtr!=0||Ptr!=0)
This is because Ptr is equal to 0 and because of this you when you try to use this pointer (Ptr->nextPtr) you crash. You probably need to do something different if Ptr is NULL.

I suggest you run this program through your debugger. It will show you exactly where the crash occurs and you can view the variables at the time of the crash.
Thanks so much! It workes fine now! there was also a little error in the writeChain(X info) function, and I had to change the function a little:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template<class X>
void Chain<X>::forgeLink(X info)
{
  if(this->startPtr!=0)
  {
    Link<X>*Ptr=this->startPtr;
    for(;;)
    {
      if(Ptr->nextPtr!=0)
        Ptr=Ptr->nextPtr;
      else
      {
        Ptr->nextPtr=new Link<X>(info,0,this->length);
        this->length++;
        break;
      }
    }
  }
  else
  {
    this->startPtr=new Link<X>(info,0,this->length);
    this->length++;
  }
}

I've never worked with a debugger before, do you know some tutorial I could learn from about it? I think that would solve alot of my problems.
I've never worked with a debugger before, do you know some tutorial I could learn from about it? I think that would solve alot of my problems.

To answer the first question, I need to know what compiler/IDE you are using, and what operating system you use. But yes learning to use the debugger is quite handy.
Topic archived. No new replies allowed.