Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>What is the definition of <code>grid</code> and how are you populating it? I bet you are doing it from the Animal constructor. At this time, the dynamic type of this is <code>Animal</code>, and not the type of the object that is eventually created.</p> <pre><code>Animal::Animal() { grid[i][j] = this; // the type of this is Animal } </code></pre> <p>Until the object is fully constructed, you cannot use the <code>this</code> pointer in a dynamic way, this includes calling virtual functions, or using the virtual function table.</p> <p>To be more specific, you need to postpone using the <code>this</code> pointer, that is to say, storing it in the <code>grid</code> array, until after the object is fully constructed.</p> <p>Here in the Animal constructor:</p> <pre><code>Animal::Animal(Savanna *savana, int x, int y) { this-&gt;savanna = savana; moved = false; breedTicks = 0; this-&gt;x=x; this-&gt;y=y; savanna-&gt;setAt(x,y,this); } </code></pre> <p>Note that you are calling <code>Savanna::setAt</code> with the <code>this</code> parameter. At this point, the dynamic type of <code>this</code> is Animal, not Wildebeest or some other thing. setAt does this:</p> <pre><code>void Savanna::setAt(int x, int y, Animal *anim) { if ((x&gt;=0) &amp;&amp; (x&lt;SAVANNASIZE) &amp;&amp; (y&gt;=0) &amp;&amp; (y&lt;SAVANNASIZE)) { grid[x][y] = anim; } } </code></pre> <p>The value of <code>anim</code> is the this pointer from the Animal constructor.</p> <p>Note a few more things. When you are constructing the list of Wildebeest, you are causing a dangling pointer:</p> <pre><code>for ( i = 0; i &lt; initialWildebeest; i++) { while (!placed) { int x = 1 + (rand() % 20); int y = 1 + (rand() % 20); if (!(w.getAt(x, y))){ **** Wildebeest fred(&amp;w, x, y); placed = 1; } } placed = 0; } </code></pre> <p>The WildeBeest named <code>fred</code> will go out of scope on the next line and be destroyed. You need to allocate it dynamically via <code>new</code>:</p> <pre><code>for ( i = 0; i &lt; initialWildebeest; i++) { while (!placed) { int x = 1 + (rand() % 20); int y = 1 + (rand() % 20); if (!(w.getAt(x, y))){ Wildebeest *fred = new Wildebeest(&amp;w, x, y); placed = 1; } } placed = 0; } </code></pre> <p>In the destrcuctor of the Savanna, there is a matching call to delete so that we do not leak memory:</p> <pre><code>Savanna::~Savanna() { // Release any allocated memory int i,j; for (i=0; i&lt;SAVANNASIZE; i++) { for (j=0; j&lt;SAVANNASIZE; j++) { **** if (grid[i][j]!=NULL) delete (grid[i][j]); } } } </code></pre> <p>You will have exactly the same problem with the Lion instances as well.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload