I'm taking a c programming course (we are still mostly using C) and we just got to dynamic allocation of memory. For one of my homeworks, I'm asked to create a function that transposes any given matrix. This function is given the following arguments as inputs: a pointer, in which are saved the matrix elements, the number of rows and of colunms. I would like this to be a void type function that changes the order of the stored elements without returning any new pointer.
I tried creating a new pointer, in which I save the elemtens in the correct order (using 2 for loops). Then what I would like to do is deallocating the original pointer (using the delete
command), assinging it to the new pointer and finally deleting the new pointer.
This unfortunately does not work (some elements turn out to be random numbers), but I don't understand why.
I hope my code is more precise and clear than my explanation:
void Traspose(float *matrix, const int rows, const int cols ){
auto *tras = new float [rows * cols];
int k = 0;
for(int i = 0; i < cols; i ){
for(int j = 0; j < rows * cols; j = cols){
tras[k] = matrix[j i];
k ;
}
}
delete[] matrix;
matrix = tras;
delete[] tras;
}
CodePudding user response:
All those lines are wrong:
delete[] matrix;
matrix = tras;
delete[] tras;
- You didn't allocate
matrix
so you don't want do delete it. - You assign
tras
tomatrix
and then youdelete tras
, after that,tras
points nowhere, nor doesmatrix
. matrix = tras
is pointless anyway, becausematrix
is a local variable, and any changes to local variables are lost after the function ends.
CodePudding user response:
You're inventing a problem where none should exist.
A matrix AxB in dimension will transpose to a matrix BxA in size. While the dimensional difference is obvious the storage requirements might not be so. Your storage is identical.
Per the function signature, the change must be done in the same memory allocated to matrix
. E.g., the results should be stored back into matrix
memory. So, don't delete that memory; leave it alone. It is both large enough to hold the transposition, and owned by the caller regardless.
Rather, do this:
void Traspose(float *matrix, const int rows, const int cols)
{
float *tras = new float[ rows * cols ];
int k = 0;
for (int i = 0; i < cols; i )
{
for (int j = 0; j < rows * cols; j = cols)
tras[k ] = matrix[j i];
}
for (int i=0; i<k; i)
matrix[i] = tras[i];
delete [] tras;
}
Note this gets quite a bit simpler (and safer) if the option to use the standard library algorithms and containers is on the table:
void Traspose(float *matrix, const int rows, const int cols)
{
std::vector<float> tras;
tras.reserve(rows*cols);
for (int i = 0; i < cols; i )
{
for (int j = 0; j < rows * cols; j = cols)
tras.emplace_back(matrix[j i]);
}
std::copy(tras.begin(), tras.end(), matrix);
}
Finally, probably worth investigating in your spare time, there are algorithms to do this, even for non-square matrices, in place without temporary storage using permutation chains. I'll leave researching those as an exercise to the OP.