How to properly free memory used by matrices? - c

I'm having a conceptual problem in OpenCV
I have the following function:
void project_on_subspace(CvMat * projectionResult_img)
{
[...]
projectionResult_img = cvReshape( projectionResult_line_normalised_centered, projectionResult_img, 0, 100 );
}
Basically I'm returning a square matrix as a result of my function.
The problem is that the actual data of my matrix is stored in "projectionResult_line_normalised_centered" (if I understood how open CV works), which means that trying to use CvReleaseMat(projectionResult_img) later in my code to free the memory will not work, as the real matrix data is elsewhere.
Is there any proper way to release the actual matrix data WITHOUT also dealing with a pointer to "projectionResult_line_normalised_centered" ?
Thanks

No, there is no other way than to keep a pointer to the result matrix (projectionResult_line_normalised_centered) around in a variable or struct member.

Related

Heap management with Eigen::Map : Is that user or Eigen::Matrix responsability?

Who does handle the heap unallocation when Eigen::Map is used with a heap memory segment to create a MAtrix ?
I couldn't find any info concerning the internal Matrix data memory segment management when Eigen::Map is invoked to build a Matrix.
Here is the doc I went through : https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html
Should I handle the memory segment deletion when I'am done with my Matrix "mf" in the code below ?
int rows(3), cols (3);
scomplex *m1Data = new scomplex[rows*cols];
for (int i = 0; i<cols*rows; i++)
{
m1Data[i] = scomplex( i, 2*i);
}
Map<MatrixXcf> mf(m1Data, rows, cols);
By now, if I settle a breakpoint in the function (./Eigen/src/core/util/Memory.h) :
EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
it's not triggered when the main exits.
May I ask you whether I should considere that I must delete the memory segment when I don't use my matrix anymore ?
Cheers
Sylvain
The Map object does not take ownership/responsibility of the memory that is passed to it. It could just be a view into another matrix. In that case, you definitely would not want it to release the memory.
To quote the tutorial page you linked:
Occasionally you may have a pre-defined array of numbers that you want to use within Eigen as a vector or matrix. While one option is to make a copy of the data, most commonly you probably want to re-use this memory as an Eigen type.
So, bottom line, you have to delete the memory you allocated and used with the Map.

Memory management during function call

I was writing a code that involves handling a 2D array of dimensions [101]X[101] in C. However I am constrained in terms of memory being used at a given point of time.
void manipulate(int grid_recv[101][101])
{
//Something
}
void main()
{
int grid[101][101];
manipulate(grid);
}
So lets say I create an array grid[101][101] in my main() and then pass it for manipulation to another function. Now does the function manipulate() copy the entire matrix grid into grid_recv i.e by this sort of passing am I using twice the amount of memory ( i.e twice the size of grid)?
No. In C, arrays cannot be passed as parameters to functions.
What you actually do is creating a pointer pointing the array. So the extra memory you use it only the size of that pointer created.

Why is a pointer used to access shared memory?

I have seen a lot of parallel programming code like finding the maximum of array, matrix multiplication, etc. use pointers. I don't understand why it is used. Example:(shseg+(offset*sizeof(float))) = sum;
The code for matrix multiplication:
shseg = shmat(handle,NULL,0);
for(row=SIZE/2;row<SIZE;row++){
for(column=0;column<SIZE;column++){
sum = 0;
for(tindex=0;tindex<SIZE;tindex++){
sum+=a[row][tindex]*b[tindex][column];
}
*(shseg+(offset*sizeof(float))) = sum;
offset++;
}
}
Can anyone explain why a pointer is used?
This is because the example you show uses shared memory API, which provides you a flat chunk of memory, not an array of, say, floats. Therefore, you need to do all your pointer manipulations manually.
You could also cast your shared pointer to float* and use an index, like this:
shseg = shmat(handle,NULL,0);
float *fshseg = (float*)shseg;
...
fshseg[index++] = sum;
Well, you have an allocated space of memory which is been shared with your program, you will be going all the way through the memory, if you didn't used a pointer you would not be able the get the memory address value, thats why you need to use it.

Ada - Dynamically reallocate array

I'm trying to write a stack based on array, that can be dynamically reallocated. The main problem I have is how to implement procedure that resizes the array. In C++ it could look like that:
template<class T, int incr>
void Vector<T, incr>::inflate(int increase) {
const int tsz = sizeof(T*);
T** st = new T*[quantity + increase];
memset(st, 0, (quantity + increase) * tsz);
memcpy(st, storage, quantity * tsz);
quantity += increase;
delete []storage;
storage = st;
}
where int quantity; and T** storage; are declared in private section.
If there is anyone who could share me some sample I'd be much grateful. I tried to look through the implementation of Ada.Containers.Vectors but argh... it's to big =P
So far I've made this Vector.ads Can anyone help?
Ok, case is solved. I've finished my Vector class (which is actually a stack build on an array). Thank everyone for help.
Just for posterity here is my code. Hope someone will learn something from it.
Code -> https://gist.github.com/496a50bc7f5cd93f8d91
If you'd like to take a look and find something worth changing just comment. ;D
If you go with Ada.Containers.Vectors, there's a helpful discussion in the Rationale for Ada 2005: ยง8.2 Lists and vectors. Basically, you instantiate the generic package with your Index_Type and Element_Type:
package Container is new Containers.Vectors (Natural, T);
Then declare a variable having the new type:
Stack : Container.Vector;
The Push procedure then becomes Stack.Append and the Pop function returns Stack.Last_Element. Note the availability of prefixed notation.
Presumably you know how to initially allocate the (empty) array for your stack.
When you need to reallocate to a larger array, allocate it into a local access variable, akin to "st" in your C++ example. Then loop though the existing, full array, copying its elements into your newly allocated one.
Free, using an instantiation of Unchecked Deallocation, the old array--that's the Elements field in your Vector record. Then set the Elements field to the variable containing the newly allocated array.
Essentially, it closely follows your C++ example, only you don't need to mess around with sizeof() and you use a copy loop instep of memset/memcpy.

Problems with malloc on OS X

I have written a some C code running on OS X 10.6, which happens to be slow so I am using valgrind to check for memory leaks etc. One of the things I have noticed whilst doing this:
If I allocate memory to a 2D array like this:
double** matrix = NULL;
allocate2D(matrix, 2, 2);
void allocate2D(double** matrix, int nrows, int ncols) {
matrix = (double**)malloc(nrows*sizeof(double*));
int i;
for(i=0;i<nrows;i++) {
matrix[i] = (double*)malloc(ncols*sizeof(double));
}
}
Then check the memory address of matrix it is 0x0.
However if I do
double** matrix = allocate2D(2,2);
double** allocate2D(int nrows, int ncols) {
double** matrix = (double**)malloc(nrows*sizeof(double*));
int i;
for(i=0;i<nrows;i++) {
matrix[i] = (double*)malloc(ncols*sizeof(double));
}
return matrix;
}
This works fine, i.e. the pointer to the newly created memory is returned.
When I also have a free2D function to free up the memory. It doesn't seem to free properly. I.e. the pointer still point to same address as before call to free, not 0x0 (which I thought might be default).
void free2D(double** matrix, int nrows) {
int i;
for(i=0;i<nrows;i++) {
free(matrix[i]);
}
free(matrix);
}
My question is: Am I misunderstanding how malloc/free work? Otherwise can someone suggest whats going on?
Alex
When you free a pointer, the value of the pointer does not change, you will have to explicitly set it to 0 if you want it to be null.
In the first example, you've only stored the pointer returned by malloc in a local variable. It's lost when the function returns.
Usual practice in the C language is to use the function's return value to pass the pointer to an allocated object back to the caller. As Armen pointed out, you can also pass a pointer to where the function should store its output:
void Allocate2D(double*** pMatrix...)
{
*pMatrix = malloc(...)
}
but I think most people would scream as soon as they see ***.
You might also consider that arrays of pointers are not an efficient implementation of matrices. Allocating each row separately contributes to memory fragmentation, malloc overhead (because each allocation involves some bookkeeping, not to mention the extra pointers you have to store), and cache misses. And each access to an element of the matrix involves 2 pointer dereferences rather than just one, which can introduce stalls. Finally, you have a lot more work to do allocating the matrix, since you have to check for failure of each malloc and cleanup everything you've already done if any of them fail.
A better approach is to use a one-dimensional array:
double *matrix;
matrix = malloc(nrows*ncols*sizeof *matrix);
then access element (i,j) as matrix[i*ncols+j]. The potential disadvantages are the multiplication (which is slow on ancient cpus but fast on modern ones) and the syntax.
A still-better approach is not to seek excess generality. Most matrix code on SO is not for advanced numerical mathematics where arbitrary matrix sizes might be needed, but for 3d gaming where 2x2, 3x3, and 4x4 are the only matrix sizes of any practical use. If that's the case, try something like
double (*matrix)[4] = malloc(4*sizeof *matrix);
and then you can access element (i,j) as matrix[i][j] with a single dereference and an extremely fast multiply-by-constant. And if your matrix is only needed at local scope or inside a structure, just declare it as:
double matrix[4][4];
If you're not extremely adept with the C type system and the declarations above, it might be best to just wrap all your matrices in structs anyway:
struct matrix4x4 {
double x[4][4];
};
Then declarations, pointer casts, allocations, etc. become a lot more familiar. The only disadvantage is that you need to do something like matrix.x[i][j] or matrix->x[i][j] (depending on whether matrix is a struct of pointer to struct) instead of matrix[i][j].
Edit: I did think of one useful property of implementing your matrices as arrays of row pointers - it makes permutation of rows a trivial operation. If your algorithms need to perform a lot of row permutation, this may be beneficial. Note that the benefit will not be much for small matrices, though, and than column permutation cannot be optimized this way.
In C++ You should pass the pointer by reference :)
Allocate2D(double**& matrix...)
As to what's going on - well you have a pointer that is NULL, you pass the copy of that pointer to the function which allocated mamory and initializes the copy of your pointer with the address of the newly allocated memory, but your original pointer remains NULL. As for free you don't need to pass by reference since only the value of the pointer is relevant. HTH
Since there are no references in C, you can pass by pointer, that is
Allocate2D(double*** pMatrix...)
{
*pMatrix = malloc(...)
}
and later call like
Allocate2D(&matrix ...)

Resources