memory allocation for object field fails

I'm writing a simple task: Adding/deleting elemets to/from a dynamic two-dimansional array (Matrix). Matrix is implemented as a struct:

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
/*mtrxFuncs.h*/

 template <typename T>
struct Mtrx {
    public:
        int height;
        int *rwsWidth;
        T** elmnts;
	Mtrx (int, int);
};

template <typename T>
Mtrx<T>::Mtrx (int h, int w ) {
			 short i(0);

			 height = h;
			 this->rwsWidth = new int[h];

			 while ( i < w )		/*initialize width of each row*/
				 rwsWidth[i++] = w;

			 i =0;
			 this->elmnts = (T**) malloc (h *sizeof(T*));

			 while ( i < h)
				 this->elmnts[i++] = new T[ rwsWidth[i] ];
}	/*end Mtrx constructor*/


Here is the main function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*main.cpp*/
#include <iostream>
#include "task1.h"
//#include "task2.h"

using namespace std;



int main (void) {
	task_1();
	//task_2();
	//task_3();
	return 0;
}


As you can see, it simpy calls task_1(), where the stuff happens...
And here is task_1():

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
/*task1.cpp*/
#include <iostream>
#include "mtrxFuncs.h"

using namespace std;

void task_1(void) {

	int height, width;
	int from, to;

	cout<< "\t\tCUT ROWS.\n";
	cout<< "INPUT DIMS:\n";
	cout<< "HEIGHT:\t", cin>> height;
	cout<< "WIDTH:\t", cin>> width;

	Mtrx<float>* Arr = new Mtrx<float> (height, width);

	fill (Arr);
	prnt (Arr);

	do {

		do {
			cout<< "INPUT WHICH ROWS TO CUT:\n";
			cout<< "FROM:\t", cin>> from;
			cout<< "TO:\t", cin>> to;
		}while ( rwRngIsInvalid(Arr, from -1, to -1) );

		Mtrx<float>* dltdBlck = getDltdBlck (Arr, from -1, to -1);

		cout<< "\nINITIAL ARRAY:\n", prnt (Arr);
		cout<< "\nDELETED BLOCK:\n", prnt (dltdBlck);

	} while ( notAllRwsDltd (Arr) );

}


Mtrx<float>* Arr is created OK.
Problems arise when I create Mtrx<flaot>* dltdBlck and call getDltdBlck() to initialize it. Here is the getDltdBlck():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename T>
Mtrx<T>* getDltdBlck(Mtrx<T>*& Arr, int from, int to) {

    short i(0), j(0), k(0);

    Mtrx<T>* tmp = new Mtrx<T>( to - from +1, Arr->rwsWidth[from] );       /*what was deleted*/
    Mtrx<T>* lftdBlck = new Mtrx<T> ( Arr->height - (to - from +1), Arr->rwsWidth[from] );       /*what is left*/

    while (i < Arr->height)
        if (i < from || to < i)
            lftdBlck->elmnts[k++] = Arr->elmnts[i++];
        else {
            tmp->elmnts[j++] = Arr->elmnts[i];
            Arr->elmnts[i++] = NULL;
        }
    Arr = lftdBlck;
    return tmp;
}


Run-time error (as I dudectued memory allocation failure) occurs when Mtrx<T>* tmp is created. Constructor launches, but at the point of allocating memory for elmnts field this->elmnts = (T**) malloc (h *sizeof(T*)) crashes.

I've tried to delete templates and use std types - same error.
Tried both new and malloc() - same error.

Major thing: why pointer to object Mtrx<float>* Arr in task_1() is created ok and in getDltdBlck() initialization of Mtrx<T>* tmp fails ? Why the same code works differently in similar (if not equal) situations ?

I'm using Code::Blocks 13.12-3 on Ubuntu 14.04. Any clarification would be appreciated. =)
Last edited on
> Run-time error occurs...
you get a run-time error, I cannot even compile.
provide a minimal testcase that does reproduce your issue.


1
2
3
4
5
6
7
8
9
template <typename T>
Mtrx<T>::Mtrx (int h, int w ) {
	short i(0);

	height = h;
	this->rwsWidth = new int[h];

	while ( i < w ) //rwsWidth may hold `h' elements, no `w'
		rwsWidth[i++] = w;



Also, you better encapsulate your memory management, make a wrapper that holds a Mtrx<T>* and solves the copies and slices.
Thanks for comments =)
Here is the testCase
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

#include <iostream>

using namespace std;

template <typename T>
struct Mtrx {
    public:
        int height;
        int *rwsWidth;
        T** elmnts;
        Mtrx (int, int);
};

template <typename T>
Mtrx<T>::Mtrx (int h, int w ) {
			 short i(0);

			 height = h;
			 this->rwsWidth = new int[h];

			 while ( i < w )
				 rwsWidth[i++] = w;

			 this->elmnts = (T**) malloc (h *sizeof(T*));       /*RUNTIME ERROR*/

                         i =0;
			 while ( i < h)
				 this->elmnts[i++] = new T[ rwsWidth[i] ];
}	/*end Mtrx constructor*/

template <typename T>
Mtrx<T>* getDltdBlck(Mtrx<T>*& Arr, int from, int to) {

	Mtrx<T>* tmp = new Mtrx<T> ( to - from +1, Arr->rwsWidth[from] );

    return tmp;
}

void testcase(void){
    unsigned height, width;

    cout<< "INPUT DIMS:\t", cin>> height>> width;
    Mtrx<float>* Arr = new Mtrx<float> (height, width);

    cout<< "DELETE ROW FROM MATRIX\n";
    Mtrx<float>* dltcBlck_3 = getDltdBlck (Arr, 2, 3);

}

int main()
{
    testcase();
    return 0;
}


Error occurs in Mtrx constructor
this->elmnts = (T**) malloc (h *sizeof(T*)); /*RUNTIME ERROR*/

Hints ?
Last edited on
you may be accessing out of bounds on line 23.
Also this->elmnts[i++] = new T[ rwsWidth[i] ]; (line 29) may be undefined behaviour.
Topic archived. No new replies allowed.