Thread: Accesing pointer to struct data

  1. #1
    Registered User mosu''s Avatar
    Join Date
    Jul 2006
    Location
    Cluj Napoca - Romania
    Posts
    10

    Unhappy Accesing pointer to struct data

    Hy all. I have this code, done it so, because it is a school project, so I am forced to use this things ...
    Anyway, I don't understand what its wrong
    Here is the code:
    //this is valuta.h:
    Code:
    typedef void* cheie;
    typedef void* valoare;
    typedef int (*FunCmp)(cheie a, cheie b);
    struct _Tabel;
    typedef _Tabel* Tabel;
    struct _Tabel{
       cheie valuta[10];
       valoare lei[10];
       int dim;
       FunCmp FC;
    };
    void creaza(Tabel& t, FunCmp f);
    valoare insereaza(Tabel &t, cheie c, valoare v);
    valoare cauta(Tabel& t,cheie c);
    //this is valuta.cpp:
    Code:
    #include <iostream.h>
    #include "valuta.h"
    void creaza(Tabel& t, FunCmp f){
       t=new _Tabel;
       t->dim=-1;
    }
    valoare cauta(Tabel& t, cheie c){
       while(t->dim>=0)
       {
       int    i=t->dim;
       cout<<"t->dim: "<<t->dim<<"   value:"<<(*(int*)t->lei[i])<<endl;
                           //here is the big problem ... i
                           //guess that t->lei[i] point to the
                           //start off the array, but how can I
                           //make it to point to each element ? :-/
       t->dim--;       //in this moment this code just prints
                           //the last value for t->dim times ...
       }
       return 0;
    }
    //this is were I populate my struct ...
    valoare insereaza(Tabel& t, cheie c, valoare v){
    
           t->dim++;
           t->valuta[t->dim]=c;
           t->lei[t->dim]=v;
           cout<<"t->dim:"<<t->dim<<endl;
           cout<<(char*)t->valuta[t->dim];
           cout<<" "<<(*(int *)t->lei[t->dim])<<endl;
    
       return v;
    }
    // and finally this is the main program, here
    //I create values and call the inserting function...
    //I also call "cauta" wich should search for a value ...
    //but you can see that is not working ...
    Code:
    #include "valuta.h"
    #include <iostream.h>
    void main(){
       Tabel t;
       FunCmp Fc;
       creaza(t, Fc);
       char val[10];
       int *plei;
       int lei;
       int nrval;
       cout<<"Cate valori ? (Maxim 10) ";//the number of values
       cin>>nrval;
       for (int i=0;i<nrval;i++){
       cout<<"Valuta dorita:";//one value, a string
       cin>>val;
       cout<<endl;
       cout<<"Valoarea in lei:";//another value, an int
       cin>>lei;
       cout<<endl;
       plei=&lei;
       insereaza(t, &val, plei);
       }
       cauta(t,val);
    }
    If I cout with:
    cout <<"t->dim: " <<t->dim <<" value:" <<t->lei[t->dim]
    it prints a memory address (the same )for 3 times (suposing t->dim = 3).
    If I cout with:
    cout <<"t->dim: " <<t->dim <<" value:" <<(*(int*)t->lei[i]) <<endl; //insteed of "i" I also may put t->dim, the result its
    //the same
    it prints the LAST value entered 3 times (suposing t->dim =3)
    Is not this the problem, in first case it prints an adrress because t->lei[t->dim] (or t->lei[i]) is a pointer to struct.
    In the second case it prints the value because the present of the dereference operator. Still in this case I don't understand why I can't wrote (*(int)t->lei[i]) because, its make sense for me. I cast to int, and I want to print the data from that location of memory ... Wright ? The compiler says: illegal indirection, but I don't really understand why ...
    So how can I make things that I can print the data from every element ?
    Any idea will be greatly apreciated ! Thank you!

  2. #2
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Well, a 'Table &' is a reference, and not a pointer. You can access member elements using the '.' operator, not the '->' one.

    http://www.parashift.com/c++-faq-lite/references.html

  3. #3
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Tonto
    Well, a 'Table &' is a reference, and not a pointer. You can access member elements using the '.' operator, not the '->' one.

    http://www.parashift.com/c++-faq-lite/references.html
    it is a reference to a pointer in this case.
    there is this stupid typedef
    Code:
    typedef _Tabel* Tabel;
    that's why I don't want to try reading that code.
    Kurt

  4. #4
    Registered User mosu''s Avatar
    Join Date
    Jul 2006
    Location
    Cluj Napoca - Romania
    Posts
    10
    Well ... this are the project requests ... It wasn't at my desire ... even if it is stupid ...
    I put all that code (sorry for this) because I just don't see, don't understand where the problem is ...
    If someone can pas through this ugly (indeed) code and give me a clue I will be verry happy.
    Thank You!

  5. #5
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by mosu'
    Well ... this are the project requests ... It wasn't at my desire ... even if it is stupid ...
    This is C++ and there are other ways then casting everything to void * to make a program generic. On the other hand this program isn't even generic because all the functions have to know about the real type of their parameters to be able to cast back.
    This is the ugliest mixture of C and C++ that I have ever seen.
    Nevertheless I took the time to correct the mistakes in your code.
    But I have to point out that a real program must not be written this way.
    I think you misunderstood the project requirements.

    //this is valuta.cpp:
    Code:
    #include <iostream> // better to use standard headers
    #include "valuta.h"
    
    using namespace std; // needed for the new header
    
    
    void creaza(Tabel& t, FunCmp f){
        t=new _Tabel;
        //t->dim=-1;
        t->dim = 0; // initially there are no values
        // we have to assign the compare function as well
        t->FC=f;
    }
    
    valoare cauta(Tabel& t, cheie c){
        // we must not change t->dim here
        // otherwise we loose information about how many records there are
        
        //while(t->dim>=0)
        //{
        //    int    i=t->dim;
        //    cout<<"t->dim: "<<t->dim<<"   value:"<<(*(int*)t->lei[i])<<endl;
                           //here is the big problem ... i
                           //guess that t->lei[i] point to the
                           //start off the array, but how can I
            //make it to point to each element ? :-/
        //    t->dim--;       //in this moment this code just prints
                           //the last value for t->dim times ...
        //}
        int    i;
        cout << "printing data" << endl;
        for ( i = 0; i < t->dim; ++i ) {
            cout << "record " << i << ":" << (char*) t->valuta[i] << " " << (int)t->lei[i]<<endl;
        }
       return 0;
    }
    
    //this is were I populate my struct ...
    valoare insereaza(Tabel& t, cheie c, valoare v){
    
        // t->dim++;  // will increment after insertion. dim will hold number of values
        // cheie is a string, need to allocate memory
        t->valuta[t->dim]=new char[10];  // I use the magic number from main
        strcpy((char*)t->valuta[t->dim], (char*)c );
        
        // this works on ia32 because a void* has the same size as an int
        // but shurely isn't portable
        // propably should allocate space for the value and put that into the table
        t->lei[t->dim]=v;
        
        cout<<"t->dim:"<<t->dim<<endl;
        cout<<(char*)t->valuta[t->dim];
        // simply cast the void * to an int
        cout<< " " << (int)t->lei[t->dim] <<endl;
        t->dim++;
       return v;
    }
    //the main program
    Code:
    #include <iostream> // better to use standard headers
    #include "valuta.h"
    
    using namespace std; // needed for the new header
    
    // a sample compare function
    int cheie_comp(cheie a, cheie b) {
        return strcmp((char*)a, (char*)b);
    }
    
    int main(){  // main returns int
        Tabel t;
        FunCmp Fc;  // this is just an uninitialized function pointer !!!!!!!!
                    // guess it should be a function that compares strings
        Fc = cheie_comp;
        creaza(t, Fc);
        char val[10];
        //int *plei;  // not needed
        int lei;
        int nrval;
        cout<<"Cate valori ? (Maxim 10) ";//the number of values
        cin>>nrval;
        for (int i=0;i<nrval;i++){
            cout<<"Valuta dorita:";//one value, a string
            cin>>val;
            //cout<<endl;  // wastes space
            cout<<"Valoarea in lei:";//another value, an int
            cin>>lei;
            //cout<<endl;  // wastes space
            // plei=&lei;  // don't need that
            // insereaza(t, &val, &lei);
            // we want to insert an int value here so cast must be here
            insereaza(t, val, (valoare)lei);
        }
        cauta(t,val);
        // the records need to be released
        for ( int i=0; i < t->dim; ++i ) {
            delete [] t->valuta;
        }
        // release the tabel
        delete  t;
    }
    Kurt
    Last edited by ZuK; 07-16-2006 at 03:59 AM.

  6. #6
    Registered User mosu''s Avatar
    Join Date
    Jul 2006
    Location
    Cluj Napoca - Romania
    Posts
    10
    Well first off all thank you. You showed me a more elegant way to solve my problem.
    But I still have some questions. If you got the time please explain me the following things:
    What is ia32 ?
    // this works on ia32 because a void* has the same size as an int
    // but shurely isn't portable
    // propably should allocate space for the value and put that into the table
    t->lei[t->dim]=v;

    I tried to modify my code in this way:
    insereaza(t, val, (valoare)lei);
    but it crashes. I didn't modify the allocation for the string. Do you have any clue why it crashes ?

    The "delete t" statement gives an assertion error in file dbgheap.c, _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) in Visual Studio 6.0. I suppose that this happens beacause the Tabel t is not allocated with new operator. Am I right ?
    I figured out where from this error ... delete t is trying to free an object that is already deallocated (I guess, earlier, with delete [] t->valuta). But this rise another question in my mind ... delete [] t->valuta, frees the memory of those chars allocated with new, or all the memory for t ?
    insereaza(t, val, (valoare)lei); val does not need a cast to pointer beacause val points to the first element of the array. Right ?

    After all this, I still did not figured out why my code was printing for t->dim times the last value inserted ...
    Thank you!
    Last edited by mosu'; 07-18-2006 at 09:59 AM.

  7. #7
    pwns nooblars
    Join Date
    Oct 2005
    Location
    Portland, Or
    Posts
    1,094
    32 bit Intel Archetecture = ia32

  8. #8
    Registered User mosu''s Avatar
    Join Date
    Jul 2006
    Location
    Cluj Napoca - Romania
    Posts
    10
    Quote Originally Posted by Wraithan
    32 bit Intel Archetecture = ia32
    Deal

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Global Variables
    By Taka in forum C Programming
    Replies: 34
    Last Post: 11-02-2007, 03:25 AM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM
  4. Another Linked List plee
    By Dragoncaster131 in forum C Programming
    Replies: 3
    Last Post: 05-15-2004, 05:40 PM
  5. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM