Cathal
Cathal

Reputation: 36

Dynamically allocated array - elements not accessible

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;
}

Upvotes: 1

Views: 1595

Answers (3)

rahul
rahul

Reputation: 1

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;
}

Upvotes: 0

Lundin
Lundin

Reputation: 213286

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.

Upvotes: 0

Mark Wilkins
Mark Wilkins

Reputation: 41232

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.

Upvotes: 5

Related Questions