2

In code:

  template<class T,int row, int col>
void invert(T (&a)[row][col])
{
T* columns = new T[col * row];
T* const free_me = columns;
T** addresses = new T*[col * row];
T** const free_me_1 = addresses;
/*cpy addresses*/
for (int i = 0; i < row; ++i)
{
    for (int j = 0; j < col; ++j)
    {
        *addresses = &a[i][j];
        ++addresses;
    }
}
addresses = free_me_1;
/*cpy every column*/
for (int i = 0; i < col; ++i)
{
    for (int j = 0; j < row; ++j)
    {
        *columns = a[j][i];
        ++columns;
    }
}
columns = free_me;
/*cpy from columns to addresses*/
for (int i = 0; i < (col * row); ++i)
{
    *addresses[i] = columns[i];
}

delete[] free_me_1;
delete[] free_me;
}

I've observed that while iterating, value of variable columns equals zero and I think thats the problem.
Thanks for your help.

P.S. I've pasted final version of this fnc. It works as intended now. Thank you everyone for your valuable help.

There is nothing we can do
  • 23,727
  • 30
  • 106
  • 194
  • How are you calling the function? –  Apr 02 '10 at 09:48
  • Hi Neil, I've added call to my fnc to my post. – There is nothing we can do Apr 02 '10 at 09:50
  • You might want to take the array by reference so that all template parameters can be deduced automatically and correctly: `T (&a)[row][col]` -- otherwise you would have to specify at least the parameter T and row, I think. – sellibitze Apr 02 '10 at 09:56
  • Do you know that `row` is ingored in `void invert(T a[row][col])`? – Alexey Malistov Apr 02 '10 at 10:07
  • @sellibitze Thanks that's great advice; Any reason why by ref arguments can be automatically deducted and by val not? – There is nothing we can do Apr 02 '10 at 10:25
  • @atch: The key here is to understand Alexey's comment. Function parameter types are special in that an array type (if it's the "top-level") is automatically converted to a pointer type. So, `a` is actually of type `T (*a)[col]` and right before the function call the "array to pointer decay" is applied. If you take the array by reference you have the reference at the "top level" which prevents this type transformation. If it weren't for this type transformation and "array to pointer decay", your code wouldn't compile because arrays can't be passed by value. – sellibitze Apr 02 '10 at 10:46
  • @atch: Note that the type of `a` that is `T (*a)[col]` doesn't mention all three template parameters. But if you use a reference to an array all three parameters would be part of the reference type which allows template argument deduction. – sellibitze Apr 02 '10 at 10:57

2 Answers2

3

You write past the buffer end because the buffer is too small.

T* columns = new T[col];

should be

T* columns = new T[col*row];

Writine past the buffer end is undefined behavior - in your case it's heap corruption because you overwrite some service data essential for the heap functioning and so delete[] fails.

Paul R
  • 208,748
  • 37
  • 389
  • 560
sharptooth
  • 167,383
  • 100
  • 513
  • 979
0

You initialize columns as a new T[col]. Then you increment columns in the inner loop, which gets execute col*row times - unless rows==1, you increment columns past the end of the array you've allocated, causing undefined behaviour.


Note that even once you fix that, your function is still very wrong - it has neither a return value nor side effects. It should be a no-op. It definitely doesn't invert its parameter.

JoeG
  • 12,994
  • 1
  • 38
  • 63