accessing unallocatted memory after changing matrix size - c

I won't bother you with all the dry details of what is the assignment and the problem I'm trying to solve, I'll cut right to the chase.
I need to fill a matrix with data. the matrix is square and everything is zero except the first 2 diagonals (meaning M[i][i] for i between 0 and n-1 and M[i][i+1] for i between 0 and n-2 are already filled)
We want to fill the matrix using this a bit complex formula.
M[i][j]=max(a+min(M[i+2][j],M[i+1][j-1]) , b+min(M[i+1][j-1],M[i][j-2]))
The result is an upper triangular matrix. You can see from the above formula that to compute the k'th diagonal, we need the k-2 diagonal. And I said the first 2 are given.
I wrote a code to fill the matrix and it is working as intended.
Here is my problem:
Since it is an upper triangular matrix, the lower half is all zero. so there is no point in wasting memory and saving it. So I thought to myself instead of allocating an n by n matrix, I will allocate n rows, and to the first row ill allocate n spaces, to the second n-1, to the third n-2 and so on...
But since we changed the dimensions of the matrix, the formula I wrote above to compute M[i][j] is different now. In my opinion, we moves all the values in the i'th row, i columns to the left. in row 0 nothing changed. in row 1, we pulled all the values 1 column to the left, etc. So if I understand correctly:
M[i][j]=M'[i][j-i]
Where M' is our new matrix. And so plugging that in the formula above:
M'[i][j]=max(a+min(M'[i+2][j-i],M'[i+1][j-1-i]) , b+min(M'[i+1][j-1-i],M'[i][j-2-i]))
However now the program to fill the matrix is not working correctly. It is filling the matrix with garbage.
Here is the code to fill the matrix:
void fill_matrix() //fills the matrix with data of optimal path, we use memoization rather than recursion, so this step is necessary.
{ //first step is to allocate the matrix. we can assume right_index==size-1 since this is the first thing we do after generating the array
int i,j;
optimum_matrix=(int**)malloc((right_index+1)*sizeof(int**));
for(j=0;j<=right_index;j++)
optimum_matrix[j]=(int*)malloc((right_index+1-j)*sizeof(int*)); //matrix allocated. upper triangular matrix. no need to allocate n^2 spaces. //to fix indices, M[i][j]=M'[i][j-i+1]. subtract i and add 1 to each column, since we moved each entry in row i, i-1 columns back.
for(i=0;i<=right_index;i++) //first diagonal
optimum_matrix[i][0]=data_array[i];
for(i=0;i<right_index;i++) //second diagonal
optimum_matrix[i][1]=get_max(data_array[i],data_array[i+1]);
for(i=0;i<=right_index;i++)
{
for(j=2;j<=right_index-i;j++)
optimum_matrix[i][j]=get_max(data_array[i]+get_min(optimum_matrix[i+2][j-i],optimum_matrix[i+1][j-i-1]),data_array[j]+get_min(optimum_matrix[i+1][j-i-1],optimum_matrix[i][j-i-2])); //here is the problem
}
}
And this is the code to print the matrix
void print_matrix()
{
int i,j,k;
for(i=0;i<=right_index;i++)
{
for(k=0;k<i;k++)
printf("0 ");
for(j=0;j<=right_index-i;j++)
printf("%d ",optimum_matrix[i][j]);
printf("\n");
}
}
Even on the first iteration of filling the third diagonal, when it enters the for loop where it says "here is the problem", if i type printf("%d",optimum_matrix[i+2][j-i]); it will print garbage. And I don't understand why since the formula agrees.
Would appreciate help. Thank you.

optimum_matrix=(int**)malloc((right_index+1)*sizeof(int**));
That isn't the right way to allocate a double array. It's allocating only one dimension of the double array. It's hard for me to follow your logic on how big you want each row and column to be. So below may not be the exact right dimensions you want. But hopefully it does illustrate how to more correctly allocate the double array.
int **optimum_matrix = malloc((right_index+1)*sizeof(int*));
for (i = 0; i < (right_index+1); i++) {
optium_matrix[i] = malloc((right_index+1)*sizeof(int));
}
BTW, I left out the check of the malloc return value for brevity. And your original code also doesn't check the return value of malloc. That should always be done.

Related

How to find the saddle points in a 2D array?

I'm trying to write pseudocode to find all the saddle points in a 2D array. The saddle points are the spots where the value is the minimum in its row, but maximum in its column, or the maximum in its row and minimum in its column.
I'm having trouble wrapping my head around how to store where these values occur, especially if there are 2 saddle points in the same row or column. I'm also not sure if I'm even approaching this correctly, maybe it can be done in a more efficient way?
The array is given by A[x][y] where x is the row and y is the column.
So far my (very basic) pseudocode is
for r=0 to y-1 // iterates through every row
for c=0 to x-1 //iterates through every element in row r
min=min(A[c][r]) //finds the minimum value in row r
for p=0 to y-1 //iterates through every element in col c
max=max(A[c][p]) //finds max in col c
if min==max
saddle point=A[c][p]
You seem to have two major problems with your pseudocode.
1) You have swapped the raws and colums
2) Passing an array element (aka value) to min/max does not make much sense. You probably should pass a row number instead and have the function to return the column number.
A simple way is to find the index of the column holding the minimum value in row r. Then find the index of the row holding the maximum value in that column.
If the two row index are the same, you have a saddle point.
Something like:
for r=0 to x-1 // iterates through every row
// Check min-max combination
c = min_in_row(r) //find index of the column holding the minimum value in row r
r2 = max_in_column(c) //find index of the row holding the maximum value in column c
if (r == r2)
{
// Saddle point found
printf("r=%d c=%d value %d is a saddle point\n", r, c, A[r][c]);
}
// Repeat the same for the max-min combination
Any saddle point can be stored with (row, column). In C:
struct Saddle { int row, col; };
If the maximum number of expected saddle points is known a result array may be used:
/* max. number of saddle points */
#define MAX_FOUND 16
/* row/col. of found saddle points */
struct Saddle found[MAX_FOUND];
/* number of found saddle points */
int nFound = 0;
To store a new result:
found[nFound].row = r;
found[nFound].col = c;
++nFound;
If the number of expected saddle points is unknown two options come in mind:
make the array size x * y (Hmm.)
allocate storage for array using malloc.
For the 2nd option malloc/realloc can be used.
There is often a trick used: If the storage runs out of memory, the realloc is used to allocate new space for multiple additional elements. Thus, the number of re-allocations is reduced because realloc is counted as "expensive" operation. In this case, two count variables are used: one for the size of allocated array, another for the numbers of actually used elements. Of course, the second must always be less or equal to the first.

unwanted changing value of an array element being address/number of element for the second array in C

I have problem that really confuses me a lot. I want to have a sparse matrix stored in 3 arrays and perform matrix/vector multiplication. Matrix and vectorB are red from a file. That's the background. The problem is in unwanted changing the value of an integer array element being an "argument" of the double array. Here is what I am doing:
int row[ELEMENTS_NO] = {0};
int col[ELEMENTS_NO] = {0};
double values[ELEMENTS_NO] = {0.0};
double vectorB[M_SIZE] = {0.0};
double res[M_SIZE]={0.0};
...reading row,col,values, from the file...
printf("\n row[0]:%d, col[0]:%d",row[0],col[0]);
for (k = 0; k < ELEMENTS_NO; k++) {
res[row[k]] = res[row[k]] + values[k]*vectorB[col[k]];
}
printf("\n\n\n row[0]:%d, col[0]:%d",row[0],col[0]);
the output of the first print is correct:
row[0]:1, col[0]:1
while the second print gives me following output:
row[0]:1352932126, col[0]:1
Why the value of col array changed after executing for loop? How to solve my problem and remain row and col elements unchanged?
Thank you for any useful information!
Check the value of row[k] and make sure it's between 0 and ELEMENTS_NO
My best guess is that one of the elements of row is negative, thus res[row[k]] would be negative.
Try running the program using valgrind, this will tell you when you have out of bounds problems for arrays.
You are indexing res[] by a value from the row array. The first one is over 1 billion, so you are changing the (more than) billionth element of res[] which I suspect is beyond the end of the array. Then anything can happen, including overwriting other variables.

Delete a column from a double array

I'm stuck here. I've got a matrix of size NxN stored in a double array. Then I want to delete a given column, lets say the first column. So I created a new double array of size NxN-1 and copy the values from the first matrix to the second one, except the 1st column of course. But then I want to set the first array to be the second array. I am blanking here.
double matrix[N][N]
//fill up the matrix code here...
// remove first column of array
double newMatrix[N][N-1];
for(i = 0; i < N; i++){
for(j = 1; j < N; j++){
newMatrix[i][j-1] = matrix[i][j];
}
}
matrix = newMatrix; // how do I set this correctly? Do I need to realloc the first array?
You cannot assign arrays in C, which I assume that your compiler tells you. To do such dynamic memory management, you will need to use pointers instead of arrays. I suggest you read up on how malloc() and free() work so that you can do what you want.
Edit:
Another solution comes to mind if you are only removing columns (or rows): keep track of the number of rows and columns used in the array. Then you can remove a row or column within the original array without creating a copy first. Just move the data past the delete column (or row) to the left (or up) then decrement your size counters. (I hope this make sense. If not let me know and I'll elaborate.)
like Code-guru said malloc() and free() should help alot, but if u simply wanted to delete the last column the you wouldn't need two arrays:
double matrix[2][3] = {1,2,3,4,5,6}; //declaring a 2 by 3 matrix
for (i=0;i<2;i++) //rows
{
for (j=0;j<3-1;j++) //columns - 1
{
printf("%.1f ",matrix[i][j]); //I chose to display matrix...
}
printf("\n");
}
Instead of accessing elements from array[i][j], one might opt to access elements from array + stride_x[x] + stride_y[y]; where array is originally introduced as double matrix[N*N]; or double *matrix = malloc(sizeof(double)*N*N);.
The stride_y[x] would originally contain offsets of columns for all rows: 0 1 2 3 4 ... N-1 and stride_y[y] would contain similar offsets multiplied with original row width 0 N 2*N 3*N..
From these 1-D arrays one can more effortlessly delete or exchange complete rows and columns, which may come handy in eg. recursive implementation of determinant calculation / Gauss Jordan elimination.

C Programming : Sum of third upper anti-diagonal a squared matrix , help badly needed please

im doing a short course in c programming and i have been so busy lately with my other classes and and helping my bother prepare for his wedding (as im his best man)that I have fallen behind and need help. any help towards this short assignment would be much appreciated as im not familiar at all with matrixs and its due in a few days.
the assignment is to Sum of third upper anti-diagonal a squared matrix .
i have been given this information:
The matrix should be a square, integer matrix of size N. In this assignment the matrix will be stored
in a 1d block of memory. You will have to convert between the conceptual 2d matrix addressing and
1d block addressing with pointer arithmetic.
Note on random numbers:
rand() function returns the next integer a sequence of pseudo-random integers in the range
[0, RAND_MAX]. RAND_MAX is a very large number and varies from system to system. To get an
integer in the range [min, max]:
(int)((min)+rand()/(RAND_MAX+1.0) * ((max)-(min)+1))
srand(SEED) is used to set the seed for rand. If srand() is called with the same seed value, the
sequence of pseudo-random numbers is repeated. To get different random numbers each time a
programme runs use time(NULL) as the seed. Rand is in stdlib.h, which needs to be included.
The program should be structured as follows.
#define N 32 // Matrix size
#define MYSEED 1234 // Last 4 digits of your student number.
int *initialise( ) // Allocate memory for the matrix using malloc
// Initialise the matrix with random integers x, 1≤ x ≤ 9
// Use 'MYSEED' as the seed in the random generator.
// Return a pointer to the matrix
void print_matrix(int *) // Print matrix on screen
int compute_diagonal(int *) // Compute your required calculation using pointer arithmetic.
// (square bracket [ ] array indexes shouldn't be used)
// Return the solution.
void finalise(int *) //free the allocated memory.
int main() // The main function should print the solution to screen.
Without doing your homework assignment for you, here's a tip:
Make a functions that abstract storing and retrieving values out of the matrix. One of the signatures should look a lot like this:
int retrieve(int* matrix, int row, int col);
Ok since this is homework and you still have a few days I will not give you an exact answer here. But I will give you some thoughts with which it should be pretty easy to come to your answer.
Indexing a matrix 1D-way: You are not allowed to use matrix[x][y] here, but only a one-dimensional array. So just take a minute and think of how the index (x,y) can be computed within a 1D array. Keep in mind that C stores elements rowwise (i.e. the elements matrix[0][0], matrix[0][1], matrix[0][2] refer to matrix[0], matrix[1], matrix[2]). It is a simply forumla in terms of X, Y and N
Filling the matrix randomly is easy, the function to create a random int is already given, just walk the matrix along and fill every element
Adding the third anti-upper diagonal. This isn really a programming question. Just sketch a small matrix on a piece of paper and see what elements you have to add. Look at their indices and than combine your newly gained knowledge with your result from my point 1 and you will know what to add up
Edit: Since you are not allowed to use the bracket operator, keep in mind that matrix[5] is the same as *(matrix+5).
I think it's fair to tell you this ;)

Entry level question about Matlab array operation

Hey guys. I have this question to ask. In C programming, if we want to store several values in an array, we implement that using loops like this:
j=0; //initialize
for (idx=1,idx less than a constant; idex++)
{
slope[j]=(y2-y1)/(x2-x1);
j++;
}
My question is in Matlab do we have any simpler way to get the same array 'slope' without manually increasing j? Something like:
for idx=1:constant
slope[]=(y2-y1)/(x2-x1);
Thank you!
Such operations can usually be done without looping.
For example, if the slope is the same for all entries, you can write
slope = ones(numRows,numCols) * (y2-y1)/(x2-x1);
where numRows and numCols are the size of the array slope.
If you have a list of y-values and x-values, and you want the slope at every point, you can call
slope = (y(2:end)-y(1:end-1))./(x(2:end)-x(1:end-1)
and get everything in one go. Note that y(2:end) are all elements from the second to the last, and y(1:end-1) are all elements from the first to the second to last. Thus, the first element of the slope is calculated from the difference between the second and the first element of y. Also, note the ./ instead of /. The dot makes it an element-wise operation, meaning that I divide the first element of the array in the numerator by the first element of the array in the denominator, etc.

Resources