Sign in to follow this  
ahayweh

Problems allocating a 2d array...

Recommended Posts

ahayweh    164
Any ideas on why this doesn't work?
void M_AllocMap( int** tileArray , int rows , int cols )
{
	tileArray = (int**)malloc(sizeof(int*)*rows );

	for( int r=0;r<rows;r++ )
	{
		tileArray[r] = (int*)malloc(sizeof(int)*cols);

		for(int c=0;c<cols;c++ ) 
		{
			tileArray[r][c] = 0;
		}
	}
}

Everything works as planned within the function , but once control is returned to the callee , the allocation is lost...

Share this post


Link to post
Share on other sites
Rattenhirn    3114
The pointer to the newly allocated array is passed by value and therefor not returned to the calling function.

You'd have to pass tileArray as int*** (that's 3 *'s) and do all the operations you did on tileArray on *tileArray instead.

Share this post


Link to post
Share on other sites
Hacksaw2201    100
try

int* tArray;

M_AllocMap(tArray, 10, 10);

or



int tArray;

M_AllocMap(&tArray, 10, 10);


void M_AllocMap( int* tileArray , int rows , int cols )
{

tileArray = (int*)malloc((sizeof(int) * rows) * cols));

memset(tileArray, 0x00, ((sizeof(int) * rows) * cols));

}

and pass the address of the pointer variable and skip the entire for loop.

This will get you contiguous memory which is easier when debugging.

How to iterate through the table? You can figure that out on your own if you understand base index(stride) displacement assembler operations. This is borderline assembler logic that you are starting to get into.

OR

listen to Rattenhir

[Edited by - Hacksaw2201 on February 22, 2008 4:18:52 PM]

Share this post


Link to post
Share on other sites
ToohrVyk    1596
Quote:
Original post by Hacksaw2201
void M_AllocMap( int* tileArray , int rows , int cols )


Still the same problem. You need to use reference semantics for the pointer-to-integer.

Quote:
tileArray = (int*)malloc((sizeof(int) * rows) * cols));
memset(tileArray, 0x00, ((sizeof(int) * rows) * cols));


I wonder why you go to the lengths of initializing the array with zero, when it would have probably been initialized with something else anyway. But even if initializing with zero does make sense, use calloc.

Quote:
int tArray;
M_AllocMap(&tArray, 10, 10);


What in the heavens did you expect this to do? Turn a stack variable into a heap-allocated buffer ???

Share this post


Link to post
Share on other sites
the_edd    2109
If you're using C++, why not something like this?


template<typename T>
class array2D
{
public:
array2D(std::size_t height, std::size_t width) :
a_(height * width),
w_(width),
h_(height)
{
}

T &operator() (std::size_t row, std::size_t col)
{
assert(row < h_);
assert(col < w_);
return a_[row * w_ + col];
}

const T &operator() (std::size_t row, std::size_t col) const
{
assert(row < h_);
assert(col < w_);
return a_[row * w_ + col];
}

private:
std::vector<T> a_;
std::size_t w_;
std::size_t h_;
};




If you're using C, then why not return the pointer to the allocated storage?


int **M_AllocMap(size_t rows , size_t cols)
{
size_t r = 0;
int **ret = malloc(sizeof *ret * rows);

if (ret != NULL)
{
for( ;r<rows;r++ )
{
ret[r] = calloc(cols, sizeof **ret);
if (ret[r] == NULL)
{
while (r--) free(ret[r]);
free(ret);
ret = NULL;
break;
}
}
}
return ret;
}




Also note:

* size_t for quantities that cannot be negative
* r must be declared outside the loop to be standard C
* there is no cast applied to the return value of malloc. A cast can hide certain errors from the compiler.
* sizeof *ret and sizeof **ret rather than sizeof(int*) and sizeof(int). You'll thank me if you ever change from using ints to another type.
* calloc is used to allocate each row, as suggested by ToohrVyk.
* out-of-memory conditions checked and handled.

But the signs are that you're using C++, so you should really be doing this in a manner that is more similar to the first snippet.

EDIT: fixed typo

[Edited by - the_edd on February 22, 2008 8:28:14 PM]

Share this post


Link to post
Share on other sites
Zahlman    1682
Quote:
Original post by the_edd
But the signs are that you're using C++


I don't see any signs of that in the OP :) Otherwise, full marks. (I would probably structure the code slightly differently, but it hardly matters.)

Share this post


Link to post
Share on other sites
the_edd    2109
Quote:
Original post by Zahlman
Quote:
Original post by the_edd
But the signs are that you're using C++


I don't see any signs of that in the OP :) Otherwise, full marks. (I would probably structure the code slightly differently, but it hardly matters.)


Well I'm going by the malloc casts (needed to shut the compiler up in C++) and the definition of the loop parameter, r, inside the loop header.


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this