Member Avatar for tcstom

Hi, I am attempting to create a dynamic array using realloc in 2 dimensions.

Currently i have managed to get it to work using realloc to dynamically resize the amount of rows but when I attempt to use realloc to dynamically resize the amount of columns per row I keep getting errors. I am currently therefore using malloc() to set the amount of columns per row.

I think that there is either something wrong in my code, or it is not possible. Below is a rough example of what I am trying to do, could someone please let me know if it is possible to use realloc to set the amount of columns per row and what would the code look like?

unsigned int ** ProtocolReceiveBuffer;
int rows = 2;
int cols0 = 1;
int cols1 = 1500;

ProtocolReceiveBuffer = realloc(ProtocolReceiveBuffer, (rows)*sizeof(unsigned int*));

ProtocolReceiveBuffer[0] = malloc((cols0)*sizeof(unsigned int));
ProtocolReceiveBuffer[1] = malloc((cols1)*sizeof(unsigned int));

Many Thanks,
Tom

realloc() only works with memory that has been previously allocated with malloc(), calloc() or realloc()

ProtocolReceiveBuffer = realloc(ProtocolReceiveBuffer, (rows)*sizeof(unsigned int*));

It is not recommended to use the same pointer to reallocate memory. If it fails you have lost the point to that memory creating a memory leak.

Member Avatar for tcstom

Just to clarify:

this part of code will be run at regular intervals:

ProtocolReceiveBuffer = realloc(ProtocolReceiveBuffer, (rows)*sizeof(unsigned int*));

ProtocolReceiveBuffer[0] = malloc((cols0)*sizeof(unsigned int));
ProtocolReceiveBuffer[1] = malloc((cols1)*sizeof(unsigned int));

every pass through the code might be one where cols0 or cols1 needs to be changed (or an additional row with a new set of columns is added/removed), if they change there will be no need to retain the data in the array, but if I call malloc every time, it would be a memory leak wouldn't it?

Thanks Aia, I know that I will need to put in error checking and proper initialisation but I want to figure out how to use realloc to set the columns per row first (if it is even possible), and I wanted to keep my code simple for you people on the forum.

I would probably initialise it by malloc()'ing a 1row by 1column array, then realloc()'ing it to whatever size I want.

> but if I call malloc every time, it would be a memory leak wouldn't it?
It would actually seem simpler.
If rows and cols are variable each time around the loop, then allocate / do stuff / free might be a lot simpler.

realloc is for when you're say reading a file, and you want 10,20,50,100,1000... items (the size just keeps growing, and you have no idea where to start).

Also, if you have a reasonable upper bound to the sizes, then just allocating the max for everything at the start would save a lot of work in the loop.

Member Avatar for tcstom

Thanks for the quick responses.
I wrote:

if they change there will be no need to retain the data

what I meant was that the data inside the columns of that row may be removed if and only if the amount of columns is changed. If no change to the amount of columns is made, the data must stay in there, hence the realloc().

The loop only runs every 5 or so seconds so speed is not a big issue, I'm developing this for an embedded application so memory is a big issue.

The buffer is for data from up to 100 odd devices some needing a buffer of 1500 bytes, others less than 1 byte, when the number of devices change or the order they are in change, the RecieveBuffer needs to adapt accordingly.

I have got half an idea of how to do it with malloc() (by writing a long winded piece of code which finds out which devices are new/have changed location etc..) but I thought it would be a lot simpler if I could just use Realloc since it already will just do nothing if the number of columns has not changed.

Member Avatar for tcstom

I still haven't solved this problem, after spending a bit of time working through some of the other code, I decided to revisit it.
I have tried to simplify my code in a way that explains sort of how I want it to work:

unsigned int ** ProtocolReceiveBuffer;
int MaxMacID = 0;

int Some_Function(int tempMacID, int bufLength) {
        int i = 0;
        if(tempMacID>MaxMacID) {
		ProtocolReceiveBuffer = realloc(ProtocolReceiveBuffer, (tempMacID+1)*sizeof(unsigned int*));
                ProtocolReceiveBuffer[tempMacID] = malloc((bufLength+1)*sizeof(unsigned int));
        }
        else
                 ProtocolReceiveBuffer[tempMacID] = (unsigned int*) realloc(ProtocolReceiveBuffer[tempMacID],(bufLength+1)*sizeof(unsigned int));
}

This code should allocate new memory if the tempMacID is greater than MaxMacID or re allocate the memory to the new bufLength if tempMacID isn't greater than MaxMacID.

The problems I am having is with the following line:

ProtocolReceiveBuffer[tempMacID] = (unsigned int*) realloc(ProtocolReceiveBuffer[tempMacID],(bufLength+1)*sizeof(unsigned int));

Thanks,
Tom

Member Avatar for tcstom

the error I am getting is a "0xC0000005: Access Violation" error, this only happens when I try to access memory realloc() ed by the problematic code.
If you need me to supply any more information, please let me know what it is you want.

Member Avatar for tcstom

OK I think I found the problem (at least the errors are gone now and the program seems to be running ok as far as I can see now. Below is how I have (sort of) set it up:

unsigned int ** ProtocolReceiveBuffer;
int MaxMacID = 0;

int Some_Function(int tempMacID, int bufLength) {
        int i = 0;
        if(tempMacID>MaxMacID) {
		ProtocolReceiveBuffer = realloc(ProtocolReceiveBuffer, (tempMacID+1)*sizeof(unsigned int*));
                ProtocolReceiveBuffer[tempMacID] = malloc((bufLength+1)*sizeof(unsigned int));
        }
        else
                 ProtocolReceiveBuffer[tempMacID] = (unsigned int*) realloc(ProtocolReceiveBuffer[tempMacID],(bufLength+1)*sizeof(unsigned int));
}

The main problem seemed to have been a thread (silly me) which was attempting to write to the buffers before they were properly set up, once I eliminated that problem I could go and experiment with changing the realloc() code.

I tried removing the first (unsigned int*) part from: ProtocolReceiveBuffer[tempMacID] = (unsigned int*) realloc(ProtocolReceiveBuffer[tempMacID],(bufLength+1)*sizeof(unsigned int)); because I haven't used that in the malloc()s, when I did that I started getting the "Access Violation" errors again, I think this was what was also preventing me from getting it to work previously.

If you have any further suggestions/see something I am doing wrong please let me know but apart from that I would say this problem is solved.

Thanks to those who attempted to help me even though I, once again, had not put up enough information...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.