2

First off: I know that new is the C++ way of doing this. I am simply showing that there is more than one way to reproduce this error, and both are incredibly frustrating.

I have two forms of this source file. I'm trying to debug yet another programming assignment, but I'm not asking for help on that. Basically, I'm trying to re-implement set as a class with fields for size and a pointer to an int array. Here's the code using new:

testnew.cpp

int main()
{
    int size = 1;
    int *elements = new int[size];
    elements[0] = 0;
    size++;
    int * temp = new int[size];
    for (int i = 0; i < (size - 1); i++)
    {
        temp[i] = elements[i];
    }
    delete[] elements;
    temp[size] = size;
    elements = temp;
    elements[1] = 1;
    delete[] elements;
}

and again, using the less-preferable alloc functions:

testalloc.cpp

int main()
{
    int size = 1;
    int * elements = (int *) malloc(sizeof(int) * size);
    elements[0] = 0;
    size++;
    elements =(int *) realloc(elements,size * sizeof(int));
    elements[1] = 1;
    free(elements);
}

In both cases, my goal is to create an array, and then append to it. However, in both cases, after building and running it in Visual Studio 2010, the array is not grown at all, and only has 1 "slot" for my items to go into. In VS's debugger, I have watches on the elements array pointer; attached is a screenshot. It is the same for both versions of the code.

My watches at the end of the program

-- the breakpoint is at the delete[]/free() call.

Seriously, what am I doing wrong? This has to be a logic error, and I've combed through a quarter dozen examples of both malloc/realloc and new, and read and re-read my textbook, and I can't see what's wrong!

I feel like I should have a line that splits the allocated memory into an array, but doesn't the new int[] call do that?

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
Tasuret
  • 155
  • 1
  • 5

5 Answers5

5

Besides any other issues with the code, you must either do what JoeG mentions and have multiple watches, or set a watch like this:

elements,5

will result in:

enter image description here

I don't know if there is an updated list for VS2010, but this still works: Symbols for Watch Variables
And: View array in Visual Studio debugger?

JoeG
  • 12,994
  • 1
  • 38
  • 63
crashmstr
  • 28,043
  • 9
  • 61
  • 79
4

Other answers have pointed out the bug in your code (temp[size] = size;), however your confusion is coming from the fact that you're misreading the debugger's output.

As far as the type system and debugger are concerned, elements isn't an array, it's a pointer. The debugger has no way of knowing whether or not it's a pointer to the first element in an array or a pointer to a single element.

If you want to see the value of elements[x] in your debugger, use the expression *(elements+x).

JoeG
  • 12,994
  • 1
  • 38
  • 63
2

In the first example, this is wrong:

temp[size] = size;

This will translate to:

temp[2] = 2;

And since arrays are zero-indexed you are writing outside your allocated area.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Ah! Curse the zero-indexing. That did end up being my problem, and I knew it was, but my inexperience with the debugger threw me off. – Tasuret Mar 12 '12 at 17:32
1

The file testnew.cpp allocates memory for size elements in temp but then sets temp[size], which is the size+1 element. Perhaps this should be

temp[i] = size;

The file testalloc.cpp commits the common error of reassigning memory to the same variable without verifying that thte call to realloc succeeds:

elements =(int *) realloc(elements,size * sizeof(int));

If realloc fails, elements will be set to null, and its original memory will be orphaned.

Adam Liss
  • 47,594
  • 12
  • 108
  • 150
1

First of all C++ is 0 indexed, so temp[size] = size; is an off by one error. And to answer your question, the type of elements is int*. That it's actually an array is not knowledge which is available to VS without code analysis. So, what you need to do is either use for example std::vector<>, boost::array or make sure that your array never detoriates to int*.

Ylisar
  • 4,293
  • 21
  • 27