0

Simplified version of my code looks like:

int * tab = nullptr;
int index = 0;
int size = 1;   // Program works unless this is init'd to something higher!
int a = 0;

while (true)
{
    int input;
    std::cin >> input;

    if (input == 0) break;
    index++;

    if (index >= size) {
        size = size * 2;
        int * newt = new int[size];

        for (int i = 0; i < a; ++i)
            newt[i] = tab[i];

        delete[] tab;
        tab = newt;
    }
    tab[a] = input;
    a++;
}

Whenever I try to change 'size' integer to be bigger than 1, the program crushes. Visual Studio shouts about memory accessibility problem, but still I can't figure what's exactly wrong. I don't have to change it, but I've struggled with this code for more than hour untill I accidently changed variable to be 1 and then it worked. I'm just curious why.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

2 Answers2

3

If size is bigger than one, then index >= size won't be true on the first iteration, none of the code that results in tab pointing to something is executed, so the tab[a] access is broken.

Your algorithm is rather hard to follow so I'm not proposing a concrete resolution, except to suggest redesigning it.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2

In addition to Lightness Races in Orbit:

Here, my approach for a revised version:

#include <iomanip>
#include <iostream>
#include <sstream>

int main()
{
  int *tab = nullptr;
  int len = 0, size = 0;
  std::stringstream in;
  in << "1 2 3 4 5 6 7 8 9 10 0";
  while (true)
  {
    int input;
    //std::cin >> input;
    in >> input;
    if (input == 0) break;
    if (len >= size) {
      size = std::max(2 * size, 1);
      int * newt = new int[size];
      for (int i = 0; i < len; ++i) newt[i] = tab[i];
      delete[] tab;
      tab = newt;
    }
    tab[len++] = input;
  }
  for (int i = 0; i < len; ++i) std::cout << ' ' << tab[i];
  std::cout << '\n';
  return 0;
}

Output:

 1 2 3 4 5 6 7 8 9 10

Live Demo on coliru

I must admit that I still didn't get why the original version should be broken. There is my try on coliru which seems to run fine (although I know – running fine doesn't mean there is no U.B.). Got it.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
  • I didn't said that my code doesn't work. It works as I wanted but can't understand why it crushes after changing 'size' to be bigger. – Kacper Paluch Nov 01 '18 at 19:13
  • Your coliru link has `size` initialised to 1. The premise of the question is that the problem is introduced by making that initial value some value greater than `1` instead. – Lightness Races in Orbit Nov 01 '18 at 19:13
  • @LightnessRacesinOrbit I re-read the question but didn't really understood. Was this the question why it works with `size = 1` but no greater values? In this case, your answer is indeed the correct one. (I took `size = 1` as it was exposed in sample of OP and just wanted to see what happens.) – Scheff's Cat Nov 01 '18 at 19:16
  • @KacperPaluch Sorry, I needed a bit help to understand your issue... ;-) – Scheff's Cat Nov 01 '18 at 19:18
  • Not a problem, really appreciate your help:) – Kacper Paluch Nov 01 '18 at 19:21
  • 1
    @Scheff Yes, that was the question. _"Whenever I try to change 'size' integer to be bigger than 1, the program crushes"_ Admittedly it's not unambiguous that the OP meant "change the `size` integer's _initial value_ to be....". – Lightness Races in Orbit Nov 01 '18 at 19:25