1

I was writing a matrix multiplication program, and to save code space I created a function make that takes a pointer to a double pointer and dynamically allocates a 2-dimensional array of given size. The arrays a and b are intialised to random values in [-2, 2]. However, when I try to run the code on gcc, I get a seg fault.

I ran the code through gdb, and the error arises when I try to set b[0][0] to a random number. When I try to print b[0][0] in gdb, I get the error:

Cannot access memory at address 0xbfebfdc3f5d77f80

However, I'm actually able to access b[0][0] before this. I can print the array just after allocating it without errors. For some reason, it's always the array b that seems to cause problems.

I've a feeling it's a pointer issue, but I can't see where. I'm not that inexperienced a programmer, but I spent the guts of 2 days trying to find out why this error keeps appearing. Can anyone shed some light?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


void make(double ***a, int m, int n)
{
  int i;
  double *tmp;


  (*a) = (double **) malloc(m*sizeof(double *));
  tmp = (double *) calloc(m*n,sizeof(double));

  if(tmp == NULL)
  {
    printf("Error with malloc.\n");
    exit(EXIT_FAILURE);
  }

  for(i=0;i<m;i++)
    (*a)[i] = &tmp[i*n];


  free(tmp);

  if(a == NULL)
  {
    fprintf(stderr, "Error with the matrix, dimensions: %d, %d. \n", m, n);
    exit(EXIT_FAILURE);
  }
}


int main()
{
  int i, j;
  int l, m, n;
  double **a, **b, **c;

  l = m = n = 8;

  srand48(time(NULL));

  make(&a, l, m);
  make(&b, m, n);
  make(&c, l, n);

  for(i=0; i<l; i++)
    for(j=0; j<m; j++)
      a[i][j] = (drand48()*4.0) - 2.0;

  for(i=0; i<m; i++)
    for(j=0; j<n; j++)
      b[i][j] = (drand48()*4.0) - 2.0;

  free(a);
  free(b);
  free(c);

  return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Cathal
  • 36
  • 8
  • 1
    In addition to the main problem Mark Wilkins has diagnosed below, note that the `if (a == NULL)` block in `make` offers no benefits as you've dereferenced `a` earlier in the function. You should either remove that block of code or move it to immediately follow allocation for `a` – simonc Dec 18 '12 at 15:32

3 Answers3

5

One problem is the call to free(tmp) in make. That is the memory that was allocated for the array. It should not be freed if you plan to continue using it.

Mark Wilkins
  • 40,729
  • 5
  • 57
  • 110
  • A second pair of eyes helps sometimes! Note that to avoid a leak, that memory does still need to be freed at some point. Since the base address of it is assigned to a[0], you can use that as the pointer for free (prior to freeing `a`). Alternatively, you could (with more tricky pointer math) allocate the entire array in one big piece instead of two allocations. – Mark Wilkins Dec 18 '12 at 15:50
0

You need to allocate memory for every row in the "would-be 2D array", you only allocate memory for the first row, then have every pointer point at that same data. This doesn't make any sense.

You don't check if the first malloc call succeeded.

You shouldn't call free from this function.

It is always best to create a true 2D array with adjacently allocated memory cells, rather than some pointer-to-pointer mess.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
0

i have pasted my partial code over here

int *nn,*kk;
int main()
{
int t=0,i;

scanf("%d",&t);
int maxx=0;
nn = new int [t];
kk = new int [t];
for(i=0;i<t;i++)
{
    scanf("%d%d",&n,&k);
    nn[i] = n;
    kk[i] = k;
    if(maxx<n)
        maxx=n;
        cout<<nn[i]<<" "<<kk[i]<<endl;
}
t=0;
for(i=0;i<t;i++)
{
    n = nn[i];
    k = kk[i];cout<<nn[i]<<" "<<kk[i]<<endl;
    //cout<<setprecision(6);
   if(k<34&&n>k)
        //cout<<a[n][k]<<endl;
        printf("%0.7lf\n",a[n][k]);
    else
        printf("0.000000\n");//cout<<"0\n";
}
delete []nn;
delete []kk;
return 0;
}
rahul
  • 1