Hi all,
I am just learning DMA, and am supposed to write 2 functions utilizing the offset technique, such that a 2-D array starts and ends the index of each dimension as the user specifies.

matrix(): creates a 2D array of float type numbers, indexing from -n to n for each dimension. A proper pointer is to be returned so that after invocation of this function, a 2D array of float type numbers and the specified starting and ending indices can be used.
free_matrix(): releases the memory allocated for the 2D array created by matrix().

I am using C, and use a UNIX-based compiler to run my program. Below is what I have:

#include <stdio.h>
#include <stdlib.h>
float** matrix(float **x, int n);
void free_matrix(float **x, int n);
int main(void)
{
   float **x;
   int i, j, n;
   scanf("%d", &n);
   x = matrix(x, n);
   for (i = -n ; i <= n ; i++)
   {
       for (j = -n ; j <= n ; j++)
          x[i][j] = i + j;
   }
   for (i = -n ; i <= n ; i++)
   {
       for (j = -n ; j <= n ; j++)
       printf("%f ", x[i][j]);
       printf("\n");
   }   
   free_matrix(x, n);
   return 0;
}
 
float** matrix(float **x, int n)
{
   int i;
   x = (float**) malloc(2 * n * sizeof(float*));
   for (i = 0 ; i < n ; i++)
   {
      x[i] = (float*) malloc(2 * n * sizeof(float));
      x[i] -= n;
   }
   x -= n;
   return x;
}

void free_matrix(float **x, int n)
{
   int i;
   x += n;
   for (i = 0 ; i < n ; i++)
      free(x[i] + n);
   free(x);
}

I keep getting the error "Segmentation fault". What is wrong with my code?

All those in blue were given in the question, so I can't change any of that. I followed the code to create the array closely with that given in my notes, which showed how to create a 2D array.

On a similar matter, I was able to create a 1D array (with starting and ending indices as -n and n respectively), but had problems freeing the memory. My function to free the memory was
void free_vector(float *x, int n)
{
free(x + n);
}
but I got the same "Segmentation Fault" error. What is wrong?

Thank you.

Regards,
Rayne

x = (float**) malloc(2 * n * sizeof(float*));

That's the problem I belive, why the 2? ,just put n like

x = (float**) malloc(n * sizeof(float*));

Then try.......

Also put in debug lines following each step,that way you can quickly find out where the problems are....


And this is really weird for (i = -n ; i <= n ; i++), I belive it's a mistake, it should be for (i = 0 ; i < n ; i++)

Since the bluse code is part of the question then we focus on how to implement this. Remember the matrix is just a linear memory layout. The first pointer ** is pointing to a piece of memory to hold an array of float pointer. Since we want to index from -n to n-1 then we want the first pointer x** to be at the center of the firt memory block obtain from malloc.
Here is my code change with comments

float** matrix(float **x, int n)
{
   int i;
   x = (float**) malloc(2 * n * sizeof(float*));
   for (i = 0 ; i < n ; i++)
   {
      x[i] = (float*) malloc(2 * n * sizeof(float));
      // The blocks memory stored in the firts array of pointers will be accessed from the midpoint of the memory for -n to n so we return the midpoint to ensure that when we indexed backwards, there is actually memory there to access.
      x[i] = x[i] + (float*)(n*sizeof(float));
   }
   x = x + (float**)(n * sizeof(float**)); // here we return the midpoint of the 
                                          // first block of memory malloc'ed
   return x;
}

// In order to free these pointers, we must remember wheere the start addresses of each block is,. First where x** is or (x - n*sizeof(float**)).
each of the x[i] pointer start address is actually at x[i] - n*sizeof(float)

The reason for the segmentation fault is bad memory access in user space memory. Using the array in the main function that is returned from matrix() indexed outside of the memory range allocated by malloc. In the first case,
x was returned as x - n. If there is no paged memory at the address returned by the first malloc minus n bytes then this is a bad memory access. The returned value should have been x + sizeof(float*)*n. That way when you access x[-n], there is actually memory there. This would have been the start address for the array of pointer alloc'ed in the first malloc statement. Same principle applies for the memory that actually holds the floats.

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.