Thread: Problem with Pointers

  1. #1
    Registered User DeliriumCordia's Avatar
    Join Date
    Mar 2012
    Posts
    59

    Problem with Pointers

    Hi guys!
    I'm new to this world, and I'm finding some problems on pointers (as most of people on the 1st time they encounter them).

    I'm going to explain my problem step by step. First of all i try to define a new struct for complex numbers (maybe some already exist).

    My code is:
    Code:
    typedef struct  {     
      float real;  
         float img;  
     } complex;
    Now I need to write a function that, when called, generates a vector of complex numbers.
    These numbers must have img part =0 and real part = +1.0 or -1.0, in random way. So I thinked I could use rand() function to generate random int numbers. If generated int %2 ==0 then real part of my complex number is +1.0, in the other case -1.0.
    Maybe there's a finer way to implement this, but it should work I think. After I filled my vector, I return a pointer to the 1st element of the vector.
    My code:
    Code:
    #include "complesso.c"
    #include <time.h>
    #define LENGTH 1023
    
    complex* randomarray(){
             
    complex vettore[LENGTH];
    complex *first;
    int i, iseed;
    iseed = time(NULL);
      srand (iseed);
      for (i=0; i<LENGTH; i++)
      {
          vettore[i].img=0.0;
          if(rand()%2==0)
          vettore[i].real=-1.0;
          else
          vettore[i].real=1.0;
        }
      first=&vettore[0];
      return first;
      
    }
    At this point, my main function should get this pointer and print, for each element of the vector, real part and img part. It compiles but it sometimes gives strange values, like 0.0, or extremely big numbers, or img parts =/=0, so I tought there's some problem with pointers.
    My code:
    Code:
    #include <stdio.h>#include "complesso.c"
    
    
    int main(){
        int i;
        complex *first;
        complex x;
        first=randomarray();
        for (i=0;i<1023;i++){
            x= *(first+i);
            printf("%d %1.1f  %1.1f \n", i, x.real, x.img);
            
            
            }
        
    
    
        system("PAUSE");
    }
    Any suggestion will be appreciated
    Last edited by DeliriumCordia; 03-27-2012 at 03:16 PM.

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Code:
    complex vettore[LENGTH];
    This is defined on the stack frame local to randomarray, which you then assign to a pointer:

    Code:
      first=&vettore[0];
    so when you return, the stack frame is reset to the previous state, anything declared and/or defined local to the function is "lost."

    If you need to return an array, you can pass it as a parameter to randomarray or malloc it within randomarray and return it.
    Last edited by Cynic; 03-27-2012 at 03:26 PM.

  3. #3
    Registered User TheBigH's Avatar
    Join Date
    May 2010
    Location
    Melbourne, Australia
    Posts
    426
    The problem is that things you declare inside functions are destroyed as soon as you return from the function. You're returning a pointer to memory locations that are not preserved. The way to do things like this is along the lines of

    Code:
    int main( void ) {
       int derp[NUM_ELEMS];
       fill_array( derp );
       return 0;
    }
    void fill_array( int *array ) {
       int i;
       for(i=0; i<NUM_ELEMS; i++ ) {
          array[i] = i*i;
       }
       return;
    }
    So what you're doing is creating your array in main. This array is preserved as long as main is active, ie. as long as the program is running. You pass a pointer to the array to your function, which allows you to modify the array contents through the pointer. The only things that are destroyed when fill_array finishes are the index variable i you declared in there, and the copy of the pointer to the array that you passed to it as the argument.
    Code:
    while(!asleep) {
       sheep++;
    }

  4. #4
    Registered User DeliriumCordia's Avatar
    Join Date
    Mar 2012
    Posts
    59
    So you suggest to create the empty array on the main function and then pass a pointer to the first element to the randomarray function, that will fill it?
    In this case randomarray should return nothing right? Because my array will be the same I passed to the randomarray function from main function...

    EDIT: got ninjad by TheBigH

    So I think I got the thread, but in this case how can I do something more "modular"? Creation of this vector will be a marginal part of my software, so I tought to delegate the creation to a function, but maybe this is the best and easiest solution...

    Gonna try.
    Last edited by DeliriumCordia; 03-27-2012 at 03:30 PM.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Correct.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Call srand(time(NULL)); only once, at the very beginning of main(). Also, you should explicitly return an int from main, usually 0.

    You can't return an array in C. Read my reply to another poster here: Need help with returning variables from a function. Hopefully that clears it up. I would probably declare the array in main and pass it in. By the way, you have unnecessary variables (x in main), and you can use array syntax (i.e. [ ]) with pointers. You could just do:
    Code:
    complex array[LENGTH];
    ...
    for (i = 0; i < LENGTH; i++) {
        printf("%d %1.1f %1.1f\n", i, array[i].real, array[i].img);
    }
    Note, C99 does have a complex number type, but not all compilers support it. It might be worth looking into if this is more than a simple exercise.

  7. #7
    Registered User DeliriumCordia's Avatar
    Join Date
    Mar 2012
    Posts
    59
    Thank you all.
    These pointers are blowing my mind...
    I tried to change both functions:
    main now should create the vector, I defined a pointer to the 1st element and pass it to randomarray function. Then inside the for cycle it points to the next element (or better, I think it does), and returns nothing because it already changed original array.

    Problem is always the same :\

    Code:
    #include "complesso.c"#include <time.h>
    #define LENGTH 1023
     randomarray(complex* index){
             
    int i, iseed;
    complex x;
    iseed = time(NULL);
      srand (iseed);
      for (i=0; i<LENGTH; i++)
      {
          *(index+i).img=0.0;
          if(rand()%2==0)
          *(index+i).real=-1.0;
          else
          *(index+i).real=1.0;
        }
      
    }
    Code:
    #include <stdio.h>#include "complesso.c"
    
    
    int main(){
        int i;
        complex vettore[1023];
        complex *first;
        complex x;
        first=&vettore[0];
        randomarray(first);
        for (i=0;i<1023;i++){
            x= *(first+i);
            printf("%d %1.1f  %1.1f \n", i, x.real, x.img);
            
            
            }
        
    
    
        system("PAUSE");
    }

  8. #8
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Code:
    randomarray(first);
    Don't pass the pointer to the vector, just pass the vector:

    Code:
    randomarray(vettore);

  9. #9
    Registered User DeliriumCordia's Avatar
    Join Date
    Mar 2012
    Posts
    59
    Oh now it works.

    *(index+i).real=-1.0; is wrong, because all the line is considered pointer I think. I tried with (*(index+i)).real and now it works (or it seems to do).

    If you have something to suggest me, here I am.

  10. #10
    Registered User DeliriumCordia's Avatar
    Join Date
    Mar 2012
    Posts
    59
    Quote Originally Posted by Cynic View Post
    Code:
    randomarray(first);
    Don't pass the pointer to the vector, just pass the vector:

    Code:
    randomarray(vettore);
    Uhm, if I pass the vector to the randomarray function, don't I work on a copy of the vector? Shouldn't I use pointers? Really, this stuff is blowing me out

  11. #11
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Quote Originally Posted by DeliriumCordia View Post
    Uhm, if I pass the vector to the randomarray function, don't I work on a copy of the vector? Shouldn't I use pointers? Really, this stuff is blowing me out
    No. When you pass an unsubscripted array, you're passing the address where the array is stored, thus you end up working on the original since you're working on locations where the values are stored, not copies of values. I think this is part of the reason people tend to think of arrays and pointers as the same, but it's not true.

  12. #12
    Registered User DeliriumCordia's Avatar
    Join Date
    Mar 2012
    Posts
    59
    Ok I try this solution.
    Is it suggested or more elegant then the one I used?

  13. #13
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by DeliriumCordia View Post
    Uhm, if I pass the vector to the randomarray function, don't I work on a copy of the vector? Shouldn't I use pointers? Really, this stuff is blowing me out
    No, you pass a copy of the pointer to the first element. The array "degrades" into a pointer to the first element when passed to a function. That means that when you do vettore[i] in the function, you are working on the same array that you have back in your main function. Look at my post #6.

    • The array notation array[i] is shorthand for *(array + i), most people probably find it easier to read the array version, so use that when possible.
    • You don't need the x variable in main. It's just unnecessary copying of values. Use vettore[i].real and vettore[i].img directly. It's clearer.
    • Don't use magic numbers. Wherever you see a 1023, replace it with LENGTH.
    • Don't include .c files, or any file that has actual code in it. A header should just contain the declarations you need to "export" the functionality in a library or other .c file. You should make a complesso.h file that has the prototype for randomarray as well as #define LENGTH 1023. Include that header in main.c and complesso.c.

  14. #14
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Quote Originally Posted by DeliriumCordia View Post
    Ok I try this solution.
    Is it suggested or more elegant then the one I used?
    There is value in passing a pointer to an array, but not in this case, so pass the array and be good.

  15. #15
    Registered User DeliriumCordia's Avatar
    Join Date
    Mar 2012
    Posts
    59
    Quote Originally Posted by anduril462 View Post
    No, you pass a copy of the pointer to the first element. The array "degrades" into a pointer to the first element when passed to a function. That means that when you do vettore[i] in the function, you are working on the same array that you have back in your main function. Look at my post #6.

    • The array notation array[i] is shorthand for *(array + i), most people probably find it easier to read the array version, so use that when possible.
    • You don't need the x variable in main. It's just unnecessary copying of values. Use vettore[i].real and vettore[i].img directly. It's clearer.
    • Don't use magic numbers. Wherever you see a 1023, replace it with LENGTH.
    • Don't include .c files, or any file that has actual code in it. A header should just contain the declarations you need to "export" the functionality in a library or other .c file. You should make a complesso.h file that has the prototype for randomarray as well as #define LENGTH 1023. Include that header in main.c and complesso.c.
    Woah that's nice, that's what I was trying to understand. Very good.
    By the way I didn't understand why shouldn't I use .c in include, and how to go for .h (what should I do and change). And i should use #define LENGTH 1023 in all my function? Or i can "import" or "inherit" from another function?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem with pointers
    By baxy77bax in forum C Programming
    Replies: 3
    Last Post: 04-13-2011, 07:13 AM
  2. Problem with pointers
    By aakashjohari in forum C Programming
    Replies: 10
    Last Post: 01-19-2011, 01:51 PM
  3. Problem with pointers
    By thennecy in forum C Programming
    Replies: 3
    Last Post: 04-14-2010, 07:59 AM
  4. Problem with malloc and pointers to pointers
    By mike_g in forum C Programming
    Replies: 7
    Last Post: 03-29-2008, 06:03 PM
  5. A problem with pointers
    By vsla in forum C Programming
    Replies: 2
    Last Post: 10-10-2007, 04:14 AM