Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Destroying mxArray that are part of an array.

Subject: Destroying mxArray that are part of an array.

From: Bruno

Date: 31 Oct, 2013 00:17:06

Message: 1 of 7

In my code I'm creating a cell array of strings. Since I don't know at compile-time how many strings I'll require I dynamically allocate mxArrayPointers.

mxArray *headers, **columns;
...
columns = (mxArray **)malloc(nColumns*sizeof(mxArray *));
...
for(int i = 0; i < nColumns; i++){
        ...
        columns[i] = mxCreateString(currColumn.c_str());
        mxSetCell(headers,i,columns[i]);
}

At the end of the function I want to destroy all the arrays, so I thought I would do the following.

for(int i = 0; i < nColumns; i++)
        mxDestroyArray(columns[i]);
mxDestroyArray(headers);
free(columns);

The code compiles, but it crashes when it attempts to execute mxDestroyArray(columns[i]). Thoughts?

Thanks,
B

Subject: Destroying mxArray that are part of an array.

From: James Tursa

Date: 31 Oct, 2013 00:52:06

Message: 2 of 7

"Bruno" wrote in message <l4s7i2$shf$1@newscl01ah.mathworks.com>...
> In my code I'm creating a cell array of strings. Since I don't know at compile-time how many strings I'll require I dynamically allocate mxArrayPointers.
>
> mxArray *headers, **columns;
> ...
> columns = (mxArray **)malloc(nColumns*sizeof(mxArray *));
> ...
> for(int i = 0; i < nColumns; i++){
> ...
> columns[i] = mxCreateString(currColumn.c_str());
> mxSetCell(headers,i,columns[i]);
> }
>
> At the end of the function I want to destroy all the arrays, so I thought I would do the following.
>
> for(int i = 0; i < nColumns; i++)
> mxDestroyArray(columns[i]);
> mxDestroyArray(headers);
> free(columns);
>
> The code compiles, but it crashes when it attempts to execute mxDestroyArray(columns[i]). Thoughts?

mxDestroyArray deep destroys all mxArrays that are part of it. So cell arrays, struct arrays, class arrays, etc, only need one mxDestroyArray call to get everything destroyed. You are crashing MATLAB because the mxDestroyArray(headers) call tries to deep destroy all the stuff it contains, but you have already destroyed them so MATLAB ends up accessing invalid memory (you already destroyed it) to attempt the destruction. You end up trying to destory the same mxArray twice. Just get rid of your loop and only do the mxDestroyArray(headers) call.

James Tursa

Subject: Destroying mxArray that are part of an array.

From: James Tursa

Date: 31 Oct, 2013 01:09:05

Message: 3 of 7

"James Tursa" wrote in message <l4s9jm$pel$1@newscl01ah.mathworks.com>...
> "Bruno" wrote in message <l4s7i2$shf$1@newscl01ah.mathworks.com>...
> > In my code I'm creating a cell array of strings. Since I don't know at compile-time how many strings I'll require I dynamically allocate mxArrayPointers.
> >
> > mxArray *headers, **columns;
> > ...
> > columns = (mxArray **)malloc(nColumns*sizeof(mxArray *));
> > ...
> > for(int i = 0; i < nColumns; i++){
> > ...
> > columns[i] = mxCreateString(currColumn.c_str());
> > mxSetCell(headers,i,columns[i]);
> > }
> >
> > At the end of the function I want to destroy all the arrays, so I thought I would do the following.
> >
> > for(int i = 0; i < nColumns; i++)
> > mxDestroyArray(columns[i]);
> > mxDestroyArray(headers);
> > free(columns);
> >
> > The code compiles, but it crashes when it attempts to execute mxDestroyArray(columns[i]). Thoughts?
>
> mxDestroyArray deep destroys all mxArrays that are part of it. So cell arrays, struct arrays, class arrays, etc, only need one mxDestroyArray call to get everything destroyed. You are crashing MATLAB because the mxDestroyArray(headers) call tries to deep destroy all the stuff it contains, but you have already destroyed them so MATLAB ends up accessing invalid memory (you already destroyed it) to attempt the destruction. You end up trying to destory the same mxArray twice. Just get rid of your loop and only do the mxDestroyArray(headers) call.
>
> James Tursa

As a follow-up, the details of the mxSetCell(headers,i,columns[i]) call are as follows:

1) Sets the i'th element of headers to the mxArray address contained in columns[i]. NOTE: Does *not* destroy anything that is already there, so if you already have something there then that address will get lost and you will have a permanent memory leak (because it is not on the garbage collection list) that cannot be recovered until you restart MATLAB.

2) Removes the mxArray address contained in columns[i] from the garbage collection list.

3) Changes the variable type of the mxArray contained in columns[i] from 4 (Temporary) to 3 (Sub-Element of cell or struct).

The disposition of the mxArray in columns[i] now becomes solely dependent on the cell or struct array that it is a part of, headers. It will hang around as long as headers hangs around, and will get destroyed automatically when headers gets destroyed.

James Tursa

Subject: Destroying mxArray that are part of an array.

From: James Tursa

Date: 31 Oct, 2013 01:15:07

Message: 4 of 7

"James Tursa" wrote in message <l4sajh$8ch$1@newscl01ah.mathworks.com>...
> "James Tursa" wrote in message <l4s9jm$pel$1@newscl01ah.mathworks.com>...
> > "Bruno" wrote in message <l4s7i2$shf$1@newscl01ah.mathworks.com>...
> > > In my code I'm creating a cell array of strings. Since I don't know at compile-time how many strings I'll require I dynamically allocate mxArrayPointers.
> > >
> > > mxArray *headers, **columns;
> > > ...
> > > columns = (mxArray **)malloc(nColumns*sizeof(mxArray *));
> > > ...
> > > for(int i = 0; i < nColumns; i++){
> > > ...
> > > columns[i] = mxCreateString(currColumn.c_str());
> > > mxSetCell(headers,i,columns[i]);
> > > }
> > >
> > > At the end of the function I want to destroy all the arrays, so I thought I would do the following.
> > >
> > > for(int i = 0; i < nColumns; i++)
> > > mxDestroyArray(columns[i]);
> > > mxDestroyArray(headers);
> > > free(columns);
> > >
> > > The code compiles, but it crashes when it attempts to execute mxDestroyArray(columns[i]). Thoughts?
> >
> > mxDestroyArray deep destroys all mxArrays that are part of it. So cell arrays, struct arrays, class arrays, etc, only need one mxDestroyArray call to get everything destroyed. You are crashing MATLAB because the mxDestroyArray(headers) call tries to deep destroy all the stuff it contains, but you have already destroyed them so MATLAB ends up accessing invalid memory (you already destroyed it) to attempt the destruction. You end up trying to destory the same mxArray twice. Just get rid of your loop and only do the mxDestroyArray(headers) call.
> >
> > James Tursa
>
> As a follow-up, the details of the mxSetCell(headers,i,columns[i]) call are as follows:
>
> 1) Sets the i'th element of headers to the mxArray address contained in columns[i]. NOTE: Does *not* destroy anything that is already there, so if you already have something there then that address will get lost and you will have a permanent memory leak (because it is not on the garbage collection list) that cannot be recovered until you restart MATLAB.
>
> 2) Removes the mxArray address contained in columns[i] from the garbage collection list.
>
> 3) Changes the variable type of the mxArray contained in columns[i] from 4 (Temporary) to 3 (Sub-Element of cell or struct).
>
> The disposition of the mxArray in columns[i] now becomes solely dependent on the cell or struct array that it is a part of, headers. It will hang around as long as headers hangs around, and will get destroyed automatically when headers gets destroyed.

2nd follow-up: Given the above information, this variation of what you originally did would have worked (but no point in doing it this way):

for(int i = 0; i < nColumns; i++) {
        mxDestroyArray(columns[i]);
        mxSetCell(headers,i,NULL); // Get rid of this reference to it since it is destroyed
}
mxDestroyArray(headers);

James Tursa

Subject: Destroying mxArray that are part of an array.

From: James Tursa

Date: 31 Oct, 2013 01:27:08

Message: 5 of 7

"Bruno" wrote in message <l4s7i2$shf$1@newscl01ah.mathworks.com>...
> ...
> columns = (mxArray **)malloc(nColumns*sizeof(mxArray *));
   :
> free(columns);

Is there some reason you are using malloc and free instead of mxMalloc and mxFree?

James Tursa

Subject: Destroying mxArray that are part of an array.

From: Bruno

Date: 31 Oct, 2013 03:32:11

Message: 6 of 7

"James Tursa" wrote in message <l4sblc$lm3$1@newscl01ah.mathworks.com>...
> "Bruno" wrote in message <l4s7i2$shf$1@newscl01ah.mathworks.com>...
> > ...
> > columns = (mxArray **)malloc(nColumns*sizeof(mxArray *));
> :
> > free(columns);
>
> Is there some reason you are using malloc and free instead of mxMalloc and mxFree?
>
> James Tursa

James,

Thanks for your prompt replies. However, I don't think what you described is the problem here. When I remove the mxDestroy for-loop and the free(columns) and replace it with a single mxDestroy(columns[0]) I still crash the application.

As far as mxMalloc and mxFree, is there any difference between mxMalloc and malloc and mxFree and free?

Thanks,
B

Subject: Destroying mxArray that are part of an array.

From: James Tursa

Date: 31 Oct, 2013 08:23:05

Message: 7 of 7

"Bruno" wrote in message <l4sivr$p8g$1@newscl01ah.mathworks.com>...
> "James Tursa" wrote in message <l4sblc$lm3$1@newscl01ah.mathworks.com>...
> > "Bruno" wrote in message <l4s7i2$shf$1@newscl01ah.mathworks.com>...
> > > ...
> > > columns = (mxArray **)malloc(nColumns*sizeof(mxArray *));
> > :
> > > free(columns);
> >
> > Is there some reason you are using malloc and free instead of mxMalloc and mxFree?
> >
> > James Tursa
>
> James,
>
> Thanks for your prompt replies. However, I don't think what you described is the problem here. When I remove the mxDestroy for-loop and the free(columns) and replace it with a single mxDestroy(columns[0]) I still crash the application.
>
> As far as mxMalloc and mxFree, is there any difference between mxMalloc and malloc and mxFree and free?

My intent was to have you do only the mxDestroyArray(headers), not mxDestroyArray(columns[0]). Please show your current code and I can critique it again.

The mxMalloc and mxFree work like malloc and free, except that mxMalloc and mxFree work with memory that is known to the MATLAB memory manager, so they are subject to garbage collection in the event of an error return. Using malloc would potentially open you up to a permanent memory leak if there was an error return.

James Tursa

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us