Problems allocating a 2d array...

Started by
7 comments, last by the_edd 16 years, 1 month ago
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...
Advertisement
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.
double post, delete me
oh ok. That makes sense. Thanks for the re.
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]
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 ???
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]
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.)
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.


This topic is closed to new replies.

Advertisement