Thread: Structure array inside memory pointer

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    4

    Structure array inside memory pointer

    Code:
    
    typedef struct airplane{
    
    	int number;
    	char origin[10];
    
    }TAIRPLANE;
    
    typedef TAIRPLANE VECT[10];
    
    
    VECT v_airplanes;
    
    //InserAirplane() is a method which puts the number = 0 and origin = "newyork"
    
    for(i=0;i<5;i++){
    v_airplanes[i]=InsertAirplane();
    }
    
    
    // i do this to put the array of structures into the memory pointer
    // i have no idea if it is correct or not
    memcpy((ptr+0), &v_airplanes, sizeof(10));
    
    //my problem comes to accessing a variable, for example number, inside v_airplane[0], for example, through the memory pointer.
    
    //as anything like this, will always cause the same output error
    printf("Number: %d", *(ptr+0).number);
    
    //output error
    test.c:54: error: request for member ‘number’ in something not a structure or union
    Need help, if possible, figuring out how to access the atributes of a structure, or array of structures in this case, through a memory pointer, so i can use it in diferent processes. (further details explained in the code above)

    Thank you

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Code:
    memcpy((ptr+0), &v_airplanes, sizeof(10));
    What is ptr? Why add zero to it? What is sizeof(10) supposed to mean? It is not the size of v_airplanes. Perhaps you meant "sizeof(v_airplane)" or "sizeof(10*TAIRPLANE)" or "sizeof(VECT)" ?

    Even if you did memcpy this properly into ptr (which ptr must also have it's own space for all that pre-allocated), if ptr is of a different type than v_airplane, it will not have a member "number". The data will be copied into it, you get it with:
    Code:
    printf("%d %s\n",*(int*)ptr,(char*)ptr+4);
    But that is just v_airplanes[0].

    Finally,
    Need help, if possible, figuring out how to access the atributes of a structure, or array of structures in this case, through a memory pointer, so i can use it in diferent processes.
    If by "processes" you mean functions in the same program, you do not have to go thru all this for that.

    If by "processes" you mean other programs or forks, you are out of luck. One process is not allowed access to the memory of another process.
    Last edited by MK27; 12-15-2009 at 01:24 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    4
    Code:
    
    int shmid = shmget (SHMKEY, 128, 0777|IPC_CREAT);
      char *addr = (char *)shmat (shmid, 0, 0);
      ptr = (int *) addr;
    Hey there,

    Thanks for taking the time

    By processes i mean they are methods within the child, 4 methods, one each in each child, meaning 4 childs. And yes, in the same program, if you mean in the same .c file

    What i want to do is simple:

    i want to have 3 arrays, but since they are going to be used inside a child if i put information in one of them, i wont be able to get it from the process in a diferent child.

    Thats why i want to use memory pointers, somehow put an array of structures inside a position of the memory pointer (or something close to it) so i can access any array through any method of any of the 4 children.

    Something like this:

    Code:
    int state = 0;
    
    int c1, c2, c3, c4;
    c1 = fork();
    if (c1 != 0)
    {
      c2 = fork();
      if (c2 != 0)
      {
        c3 = fork();
        if (c3 != 0)
        {
          c4 = fork();
          if (c4 == 0)
          {
            //child process 4 runs this
            while (state != 3);
            CA(); //method
            exit(3);
          } else {
             //parent waiting for all returns
             wait(NULL);
             wait(NULL);
             wait(NULL);
             wait(NULL);
          }
        } else {
          //child process 3 runs this
          while (state != 2);
          PE(); //method
          state++;
          exit(2);
        }
      } else {
        //child process 2 runs this
        while (state != 1);
        CE(); //method
        state++;
        exit(1);
      }
    } else {
      //child process 1 runs this
      PA(); //method
      state++;
      exit(0);
    }
    When i wrote 10 yes i've thought about it as the number of array slots


    ps: could you further explain to me the meaning behind printf("%d %s\n",*(int*)ptr,(char*)ptr+4); How can you acces an int without any sort of variable location like *((int*)ptr+0), same as for char, why ptr+4 ? Sorry if so many "(" but im used to JAVA, just moved to C like some weeks ago.
    Last edited by muggly; 12-15-2009 at 01:40 PM.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Ah, okay. I haven't used shmem before, so I can't help you much with that. I'm looking at it a bit tho:

    IPC:Shared Memory

    Might take a few minutes. Can you pick what kind of ptr ptr is (it would appear you want int, but there is no declaration)? Why not just use a *v_airplane? Typdefing an array into VECT may (unnecessarily) complicate this.

    You can cast ptr:

    (VECT*)ptr

    but this will still not give you access to members of such as ptr[2]->number

    (Just noticed your last question -- will answer that next...)
    Last edited by MK27; 12-15-2009 at 01:52 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    4
    Well i never thought about it given what i know about pointers is extremely limited. So if i put a pointer on VECT i can access it and wherever i am in the child i can for example take the information out of a structure and then say for example put it on another VECTAUX (its a VECT still) and the information will be shared? As in i take out of [0] so if another child goes and look at [0] nothing will be there.

    Ah yes, i am sorry. ptr is as an int right now. Ooooh! Damnit, does that mean i have to make it a TAIRPLANE? So silly of me... I will try it out right now and see if it works


    Edit: Okay so, huge progress here! I've managed to access ptr, which is now of the type TAIRPLANE ---> TAIRPLANE *ptr;

    I've tried to understand what you meant with printf("%d %s\n",*(int*)ptr,(char*)ptr+4); So, i've tried including another int variable onto my structure, and the way i see it work was writting *(int *)ptr would give me the first int variable available, then by writting *(int *)ptr+1 it would give me the second one!

    Given this new knowledge i ask: This is to access [0] as you said previously... Then, i know you can guess my next question! How can i access the rest? ( i will try to find it but nonetheless wrote it here, i hope it can help someone else with the same problem )

    PS: In advance i would like to thank you from the heart for helping me, you are indeed one lovely person. This doesn't mean my questions are over though!
    Last edited by muggly; 12-15-2009 at 02:07 PM.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by muggly View Post
    ps: could you further explain to me the meaning behind printf("%d %s\n",*(int*)ptr,(char*)ptr+4); How can you acces an int without any sort of variable location like *((int*)ptr+0), same as for char, why ptr+4 ? Sorry if so many "(" but im used to JAVA, just moved to C like some weeks ago.
    Okay.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    typedef struct {
    	int n;
    	char this[32];
    } test_t;
    
    int main() {
    	test_t x;
    	void *ptr = (void*)&x;
    	strcpy(x.this,"hello world");
    	printf("%s\n", (char*)ptr+(sizeof(int)));
            return 0;
    }
    How does this work? ptr points to x. The first thing in x is an int. Unless the compiler added padding to our struct, which it almost certainly will not do after an int, the next thing in x should start sizeof(int) bytes past it's start. We want to cast that location as a char*.

    The problem with this method, that makes it potentially unreliable, is that the compiler can pad the struct to make it a multiple of word size (4 bytes) -- I think it is more complicated than that, but pretty sure the bottom line is that it wants multiples of 4. You can make that easy by insuring that the struct is, so that no padding will be used.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    A better way to code that (to avoid alignment/padding issues) is to do something like this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    #define offset_of(type, member) ((size_t)&((type*)0)->member)
    
    typedef struct {
    	int n;
    	char this[32];
    } test_t;
    
    int main() {
    	test_t x;
    	void *ptr = (void*)&x;
    	strcpy(x.this,"hello world");
    	printf("%s\n", (char*)ptr+ offset_of(test_t, this));
            return 0;
    }
    bit∙hub [bit-huhb] n. A source and destination for information.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by bithub View Post
    Code:
    	printf("%s\n", (char*)ptr+ offset_of(test_t, this));
    Hey, I learned something new today.

    So muggly, you should be able to combine that and sizeof(TAIRPLANE) to reach all elements and members, eg.

    ptr+5*sizeof(TAIRPLANE)

    would give you v_airplanes[5].
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Dec 2009
    Posts
    4
    Yeah thank you so much guys, seriously

    Although i found out a new way to do what i wanted i really learned a lot and it enriched my knowledge of C, T H A N K - Y O U ))))

    PS: will attempt to explain why!

    Okay so, in this example what i want to do is i have two arrays of a structure and i want to use them with pointers, here's what i do first:

    Code:
    #define SHMKEY (key_t)0x10     //you need this one for shared memory
    #define SHMKEY2 (key_t)0x9     // 0x9 because you want to take a hand on a diferent segment of memory (i think! haven't had time to test it more, but it works )
    
    #define DIM_COUNTRY 4 // this is to define a size for the array of structures
    then we have the structures and they're pointers:

    Code:
    struct Person {
    	int id;
    	char name[10];
    };
    
    struct Country {
    	struct Person person[DIM_COUNTRY];
    };
    
    struct Turma  *country;
    struct Turma  *town;
    Okay so, now we need the shared memory variables!

    Code:
            int shmid;
            int shmidd;
         
            shmid = shmget(SHMKEY, sizeof(struct Country), IPC_CREAT | 0777);
            shmidd = shmget(SHMKEY2, sizeof(struct Country), IPC_CREAT | 0777);
    Don't worry too much about the last parameter IPC_CREAT | 0777 i have no idea what it is.

    Follow the leader on 2nd parameter, sizeof(struct <your_struct_array>) !

    Why two shmid? Because as you can see right after them, the first parameter is what we defined right in the begining, one is SHMKEY points to memory 0x10 and the other is SHMKEY2 points to 0x9, otherwise both of your arrays of structures would point to the same memory segment and even though you would think you had diferent information because you had two diferent arrays you dont, they're pointing at the same location.

    Imagine having 2 arrays, but they are part of one big array, if you had only ---> shmid = shmget(SHMKEY, sizeof(struct Turma), IPC_CREAT | 0777);
    what would happen would be, both the information in your 2 arrays would be exactly the same, because they're source would be equal.

    Moving on!

    How do you access, and how do you put information into them? Quite easy! Except for the char part, thats why i included it!

    Code:
                    strcpy(country->person[0].name, town->person[0].name);
                    (country->person[0]).id=(town->person[0]).id;
                    (turma->person[0]).id=0;
                    strcpy(town->person[0].name, "Filipe");
    Okay so, first thing. To store information all you need to do is this:

    country -> person [0] . id = 1;
    pointer array position variable int value

    Now to store a string! Because this is C you can't do it like in java and simply = "string" you must do this:

    Code:
        strcpy(country->person[0].name, "Filipe");
    
       // strcpy(designated_name_for_variable_of_class.atribute, "write!");
    So, because my pointer is country i have to put it first because it is what i want to change,
    country->person[0] because its my array of persons in the position 0
    country->person[0].name because its the name of my person in the position 0 of my array country that i want to change!

    so going back a bit...

    Code:
                    strcpy(country->person[0].name, town->person[0].name);
                    (country->person[0]).id=(town->person[0]).id;
                    (turma->person[0]).id=0;
                    strcpy(town->person[0].name, "Filipe");
    So, to copy information from one string to the other, you just have to do what i did there!

    Note the first line, i copy to country->person[0].name the string that is within town -> person[0].name

    In the second i equal (because its a int) my country->person[0].id to my town->person[0].id

    so my country->person[0].id has the value of town->person[0].id !

    In the next two following lines of code it is how you can change just one position of the array singularly without copying from one array to the next!



    I hope you understood it all, and i hope that it helps you programming better! ( this is mostly to the new people who might read the topic, given you two might know what i just wrote :P )

    Thanks !
    Last edited by muggly; 12-15-2009 at 04:26 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. Replies: 6
    Last Post: 01-16-2007, 09:21 PM
  4. question about multidimensional arrays
    By richdb in forum C Programming
    Replies: 22
    Last Post: 02-26-2006, 09:51 AM
  5. pointer to an array in a structure
    By samual_van in forum C++ Programming
    Replies: 2
    Last Post: 04-16-2005, 10:51 AM