Warwick
Warwick

Reputation: 11

2D pointer arithmetic in C

I am attempting to swap 2 elements in a 2D array in C, with no luck.

Thanks for the answers so far, but I have edited this code to make things clearer about what I am doing.

typedef struct smystruct { /* stuff... */ } mystruct;

void nswap( mystruct ** a, mystruct ** b )
{
  mystruct * tmp = *a;
  *a = *b;
  *b = tmp;
}

void nqsort( mystruct ** h, int m, int n )
{
  double key = 0.0;
  int i = 0, j = 0, k = 0;

  if( m < n ) {
    // choose the pivot point...
    k = (m + n) / 2;

    nswap( &h[ n ], &h[ k ] );

    key = (*h+m)->prob;

    i = m + 1;
    j = n;

    while ( i <= j ) {
      while ( (i <= n) && (*h+i)->prob <= key )
        i++;
      while ( (j >= m) && (*h+j)->prob > key )
        j--;
      if ( i < j ) {
        nswap( &h[i], &h[j] );
      }
    }

    // swap two elements
    nswap( &h[m], &h[j] );

    // recursively sort the lesser list
    nqsort( h, m, j-1 );
    nqsort( h, j+1, n );
  }
}

int main()
{
  mystruct * p = NULL;

  // get the number of nodes (m)...
  fscanf( in, "%d", &m );

  // allocate memory for the node and connectivity matrix arrays...
  p = (mystruct*)malloc( sizeof( mystruct ) * m );

  // read in the location and associated probabilities!...
  for ( ; loop < m ; ++loop ) {
    mystruct * tmpnode = p + loop;
    tmpnode->str = (char*)malloc( sizeof( char ) * 1024 );
    fscanf( in, "%s %lf", (char *)tmpnode->str, &tmpnode->prob );
  }

  nqsort( &p, 0, m );
}

Needless to say this does not work. I have searched for examples and nothing seems to work. Advise for the n00b would be appreciated.

Upvotes: 1

Views: 827

Answers (3)

Joel Falcou
Joel Falcou

Reputation: 6357

Multiple stuff is wrong there.

1/ Your 2D array is badly allocated (or code is missing). 2/ A proper way to do such 2D allocation is to use Iliffe pointer (as advised in Numrical Recipes in C/C++).

mystruct** alloc_array( int h, int w )
{
  int i;
  mystruct** m = malloc(h*sizeof(mystruct*));
  m[0] = malloc(h*w*sizeof(mystruct));
  for(i=1;i<h;i++) m[i] = m[i-1]+w;
  return m;
}

void release_array(mystruct** m)
{
  free( m[0] );
  free( m);
}

This way of allocating brings you both a contiguous block of memory (which is easier to handle, is more cache friendly, dont require to do some index computation) and a [][] access.

Your swap function then become :

void swap( mystruct* a, mystruct* b )
{
  mystruct tmp = *a
  *a = *b;
  *b = tmp;
}

and can be called like :

swap( &some_tab[i][j], &some_other_tab[u][v] );

In a full example :

int main()
{
  mystruct** my_array = alloc_array(3,4); /* 3x4 mystruct array */

  /* fill the array */

  /* Swap some */

  swap( &my_array[2][1], &my_array[0][3] );


  release_array(my_array);
}

Upvotes: 2

Piotr Praszmo
Piotr Praszmo

Reputation: 18340

You are passing pointer to array to your function. That means h has only one element.

swap( &p, 10 );

Should be:

swap( p, 10 );

That means you need to change your function to accept arrays of mystruct or change p to array of pointers to mystruct.

And, as KennyTM suggested the last element has index 9 not 10.

Upvotes: 0

kennytm
kennytm

Reputation: 523794

  1. The last element has index count-1, not count.

    h[0]  h[1]  h[2]  h[3]  h[4]  h[5]  h[6]  h[7]  h[8]  h[9]
    ----------------------------------------------------------
                         total 10 elements
    
  2. I don't know what is fwnodes, perhaps you mean h.

Upvotes: 2

Related Questions