Pointer address

This is a discussion on Pointer address within the C Programming forums, part of the General Programming Boards category; I built a program that sorts a list of numbers. It sorts the numbers correctly. However, I want the address ...

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    12

    Pointer address

    I built a program that sorts a list of numbers. It sorts the numbers correctly. However, I want the address of the numbers to stay the same. For example, I want this input/output.

    Enter the length of the list: 4
    Enter the integer list: 7 4 1 3
    List before sorting: element (address)
    7 (229310)
    4 (229314)
    1 (229318)
    3 (229322)

    List after sorting: element (address)
    1 (229318)
    3 (229322)
    4 (229314)
    7 (229310)

    right now it keeps the address the same and outputs:

    List after sorting: element (address)
    1 (229310)
    3 (229314)
    4 (229318)
    7 (229322)

    any suggestions?

    here is my code:
    Code:
    #include <stdio.h>
    #define N 100
    
    void read_matrix(int *m, int n);
    void print_matrix(int *m,int n);
    void InsertionSort(int *a, int m);
    
    main()
    
     {
    	int m[N], n, *p, *q;
    	p = &m[0];
    	q = p;
    	printf("\n\nEnter the length of the input list:");
    	scanf("%d", &n);
    	printf("\n\nEnter the integers list:");
    	read_matrix(p, n);
    
    	printf("\n\nList before sorting: element (address)\n");
    	print_matrix(p, n);
    	
    	InsertionSort(p, n-1);
    	printf("\n\nList after sorting: element (address)\n");
    	print_matrix(p, n);
    
    	
    
     }
    
    void read_matrix(int *m, int n)	
      {
    	int i;
    	for(i=0; i<n; m++, i++)
    		scanf("%d", m);
      }
    
    
    void print_matrix(int *m, int n)
     {
    	int i;
    	for(i=0; i<n; i++, m++)
    	{
    		printf(" %d (%d)\n", *m, &m+i);
    	}
      }
    
    void InsertionSort(int *a, int m)
      {
    	int temp;
    	int i, j;
    	for(i=1; i<=m; i++)
    		{
    			temp = a[i];
    			j = i-1;
    			while( a[j]>temp && j>=0)
    			{
    				a[j+1] = a[j];
    				j--;
    			}
    			a[j+1]=temp;
    		}
      }

  2. #2
    Registered User
    Join Date
    Aug 2003
    Posts
    51
    first thing, since arrays are treated as pointers both lines below do the same thing

    Code:
    p = &m[0];
    
    p = m
    Now with the addresses you can't do anything about it. It's an array which is a block of contiguous memory allocations. In your case, the array are contiguous ints.

    When you sort the array, you are changing what each memory location holds. Which means you can't keep the address for each number.

    The only way to do it is by using some sort of linked list. Maybe another array which store the positions of the int's in the other array.

    eg

    positions - 3 2 4 1 0
    list - 4 3 1 0 2

    then you can keep the addresses with the associated number

  3. #3
    Registered User
    Join Date
    Oct 2003
    Posts
    12
    Originally posted by Kyro

    The only way to do it is by using some sort of linked list. Maybe another array which store the positions of the int's in the other array.

    eg

    positions - 3 2 4 1 0
    list - 4 3 1 0 2

    then you can keep the addresses with the associated number
    can you explain this a little further?

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>can you explain this a little further?
    Use dynamic allocation, that why you can move the pointers around.
    Code:
    #include <stdio.h> 
    #include <stdlib.h> 
    
    int main ( void )
    {
      int *parray[10] = {0};
      int i;
      
      for (i = 0; i < 10; i++)
      {
        parray[i] = malloc(sizeof(*parray));
        *parray[i] = i*10;
      }
      
      for (i = 0; i < 10; i++)
      {
        printf ("%2d (%p)\n", *parray[i], (void*)parray[i]);
      }
      
      for (i = 0; i < 5; i++)
      {
        int *temp;
        temp = parray[i];
        parray[i] = parray[i+5];
        parray[i+5] = temp;
      }
      
      puts ("After order change:");
      for (i = 0; i < 10; i++)
      {
        printf ("%2d (%p)\n", *parray[i], (void*)parray[i]);
      }
      
      return 0;
    }
    
    /*
    
     0 (008428B8)
    10 (008428C8)
    20 (008428D8)
    30 (008428E8)
    40 (008428F8)
    50 (00842908)
    60 (00842918)
    70 (00842928)
    80 (00842938)
    90 (00842948)
    After order change:
    50 (00842908)
    60 (00842918)
    70 (00842928)
    80 (00842938)
    90 (00842948)
     0 (008428B8)
    10 (008428C8)
    20 (008428D8)
    30 (008428E8)
    40 (008428F8)
    
    */
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    Registered User
    Join Date
    Oct 2003
    Posts
    12
    There should be a way to do this without having to use the standard library or dynamic allocation. What I need to do is change what element the pointers are pointing to instead of changing the values of the elements.

    e.g.

    a pointer array p[0, 1, 2, 3, 4, 5]
    the values entered into the array m = m[6, 3, 1, 5, 2, 4]

    p[0] should point to m[2]
    p[1] should point to m[4]
    p[2] should point to m[1]
    p[3] should point to m[5]
    p[4] should point to m[3]
    p[5] should point to m[0]

    I'm racking my brain trying figure this out. Any suggestions?

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    So make two arrays, both the same size, of different types. Make the first one an array of whatever type of data you're going to store, and make the second an array of pointers to that type. Then just sort the second array by moving the pointers around so they point at different slots of the main array.

    Or hell, don't even do that. Make one array that holds your stuff, and make an array of integers that has the same number of elements as your first. Then sort the second list, the list of integers, so that the number contained in the second list is the index of the first array's element. Like so:
    Code:
    int stuff[3] = { 3, 1, 2 };
    int sort[3] = { -1, -1, -1 };
    int x = 0;
    
    ... sort it ...
    
    for( x = 0; x < 3; x++ )
        printf("%d is at (%p)\n", stuff[ sort[x] ], (void*)&stuff[ sort[x] ] );
    This is amazingly easy, so I'll leave the sorting to you.

    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Oct 2003
    Posts
    12
    Originally posted by quzah
    Then just sort the second array by moving the pointers around so they point at different slots of the main array.

    Hell, call me slow, but I just can't figure this out. I understand to make the array to hold the integers, and then make a pointer array to point to the integer array. As it is now, I have it sort the integer array, which isn't what I want. I can't figure out how to sort the pointer array so that the what each pointer points to changes and the integer array stays the same.

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    If I were using qsort to sort an array of int pointers by the ints they are pointing to, I might try the following.
    Code:
    /*
    a pointer array p[0, 1, 2, 3, 4, 5]
    the values entered into the array m = m[6, 3, 1, 5, 2, 4]
    
    p[0] should point to m[2]
    p[1] should point to m[4]
    p[2] should point to m[1]
    p[3] should point to m[5]
    p[4] should point to m[3]
    p[5] should point to m[0]
    */
    #include <stdio.h>
    #include <stdlib.h>
    
    int cmp(const void *a, const void *b)
    {
       const int *const *x = a;
       const int *const *y = b;
       if ( **x > **y ) return 1;
       if ( **x < **y ) return -1;
       return 0;
    }
    
    void show(const int *m, const int *const p[], size_t size)
    {
       size_t i;
       for ( i = 0; i < size; ++i )
       {
          printf("m[%lu] = %d, p[%lu] = %p, *p[%lu] = %d\n", (long unsigned)i,
                 m[i], (long unsigned)i, (void*)p[i], (long unsigned)i, *p[i]);
       }
    }
    
    int main (void)
    {
       const int m[] = {6,3,1,5,2,4}, *p[sizeof m / sizeof *m];
       size_t i;
    
       for ( i = 0; i < sizeof m / sizeof *m; ++i )
       {
          p[i] = &m[i];
       }
    
       puts("Before:");
       show(m, p, sizeof m / sizeof *m);
    
       qsort(p, sizeof p / sizeof *p, sizeof *p, cmp);
    
       puts("After:");
       show(m, p, sizeof m / sizeof *m);
    
       return 0;
    }
    
    /* my output
    Before:
    m[0] = 6, p[0] = 0012FF74, *p[0] = 6
    m[1] = 3, p[1] = 0012FF78, *p[1] = 3
    m[2] = 1, p[2] = 0012FF7C, *p[2] = 1
    m[3] = 5, p[3] = 0012FF80, *p[3] = 5
    m[4] = 2, p[4] = 0012FF84, *p[4] = 2
    m[5] = 4, p[5] = 0012FF88, *p[5] = 4
    After:
    m[0] = 6, p[0] = 0012FF7C, *p[0] = 1
    m[1] = 3, p[1] = 0012FF84, *p[1] = 2
    m[2] = 1, p[2] = 0012FF78, *p[2] = 3
    m[3] = 5, p[3] = 0012FF88, *p[3] = 4
    m[4] = 2, p[4] = 0012FF80, *p[4] = 5
    m[5] = 4, p[5] = 0012FF74, *p[5] = 6
    */
    Last edited by Dave_Sinkula; 10-30-2003 at 09:02 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Increment the address stored in a pointer???
    By patricio2626 in forum C++ Programming
    Replies: 9
    Last Post: 04-04-2007, 06:36 PM
  2. [beginner] get file address from file pointer
    By taisao in forum C Programming
    Replies: 14
    Last Post: 03-30-2007, 09:46 AM
  3. Should i pass address of pointer or just pointer???
    By howhy in forum C++ Programming
    Replies: 11
    Last Post: 09-02-2005, 04:05 AM
  4. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  5. Im so lost at . .
    By hermit in forum C Programming
    Replies: 18
    Last Post: 05-15-2002, 01:26 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21