Thread: calloc and shmget

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    5

    calloc and shmget

    Hi,

    I have to create a dynamic matrix with a number of rows and columns.
    So i allocate memory for this with following code:

    Code:
    struct field_struct
    {
       float id;
       int data;
       float data2;
    }field;
    
    struct field_struct ** matrix;
    matrix = (struct field_struct **) calloc(1,rows*sizeof(struct field_struct));
    if (matrix != NULL)
    {
    	for(i=0;i<rows;i++)
    	{
                   matrix[i] = (struct field_struct*) calloc(1,columns*sizeof(struct field_struct));
            }
    }
    So every field of the matrix is a structvariable.
    Now i want to save this matrix in a shared memory and free the memory of the allocation.

    Code:
    int shID=shmget(0001, rows*columns*(sizeof(int)+2*sizeof(float)), IPC_CREAT | 0666);
    int *myPtrshID = shmat (shID, 0, 0);
    myPtrshID=matrix;
    shmdt (myPtrshID);
    // shmctl?
    for (i=0; i<rows; i++)
          free(matrix[i]);
    free(matrix);
    My questions:
    What is correct so far? :/
    Is the size in shmget correct?
    How can i copy the matrix in the shared memory?
    And how can i access the matrix in another function?

    I'm thanktful for any hint.
    Thanks in advance,
    Alex

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    struct field_struct ** matrix;
    matrix = (struct field_struct **) calloc(1,rows*sizeof(struct field_struct));
    if (matrix != NULL)
    {
    	for(i=0;i<rows;i++)
    	{
                   matrix[i] = (struct field_struct*) calloc(1,columns*sizeof(struct field_struct));
            }
    }
    Not quite . . . consider this.
    Code:
    struct field_struct ** matrix;
    matrix = (struct field_struct **) calloc(1,rows*sizeof(struct field_struct *));
    if (matrix != NULL)
    {
    	for(i=0;i<rows;i++)
    	{
                   matrix[i] = (struct field_struct*) calloc(1,columns*sizeof(struct field_struct));
            }
    }
    You want an array of pointers to the structure type in the first case.

    Also, this probably isn't correct.
    Code:
    (sizeof(int)+2*sizeof(float))
    The compiler will likely add padding to your structure, making it larger than you think it is. Anyway, it's just safer to use
    Code:
    sizeof(struct field_struct)
    I don't think you're using shared memory properly. The idea with shared memory is that you put your data in it. So you don't want to create an array and then somehow "tie" it to the shared memory; instead, use the memory directly. With judicious casting you should be able to access it however you like.

    How, I wouldn't know, having never used shmget(). I suggest you find a tutorial on it (or read the man pages, though they're a bit dense).

    Just so you know: "0001" is actually an octal number, since it starts with 0. Might trip you up when you get to 0008.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    5
    hi,
    Code:
    matrix = (struct field_struct **) calloc(1,rows*sizeof(struct field_struct));
    also works but
    Code:
    matrix = (struct field_struct **) calloc(1,rows*sizeof(struct field_struct *));
    allocates less memory, right? changed it and works, too

    using
    Code:
    sizeof(struct field_struct)
    seems the best way considering possible changes of the struct

    The reason I'm using calloc is the initialization of all variables in every field. I thought that it would be the right way to do it this way :/ First allocate memory in "main memory" and do other things with the variable optionally and then copy the "result" to the shared memory area where other processes can use it...

    I read a tutorial and found it the other way round means first map the shared memory and then alter it / write in it directly
    But the correct assignment I'm not sure of.

    So here is what I'm thinking:

    Code:
    //create memory area 
    // "5478" is a "random" number, size is matrixdimension*size of the struct, 0666 read and write for other processes...
    int shID=shmget(5478,rows*columns*sizeof(struct field_struct,0666);
    // pointer to the matrix?! right? or two times "*"?
    struct field_struct *myPtr;
    // ID vof shmget, 0 for free assignment of memory, 0 for read/write
    myPtr = shmat(shID, 0, 0);
    
    // adress from pointer equals the matrix adress?!
    matrix =myPtr;
    
    // matrix 
    struct field_struct ** matrix;
    matrix = (struct field_struct **) calloc(1,rows*sizeof(struct field_struct *));
    if (matrix != NULL)
    {
    	for(i=0;i<rows;i++)
    	{
                   matrix[i] = (struct field_struct*) calloc(1,columns*sizeof(struct field_struct));
            }
    }

    As you can see the order in which the assignments have to be used is not clear to me


    So the aim is following:
    one function creates a matrix and another variable structure
    these should be stored in a shared memory area
    so that another function can access the data and use it for calculations and then alter the shared memory area

    Can anyone help me?
    Alex

  4. #4
    Registered User
    Join Date
    Sep 2009
    Posts
    5
    I Think I found a solution:

    By using memcpy after calloc and shmat and then freeing the memory area of calloc:

    Code:
    struct field_struct ** matrix;
    matrix = (struct field_struct **) calloc(1,rows*sizeof(struct field_struct *));
    if (matrix != NULL)
    {
    	for(i=0;i<rows;i++)
    	{
                   matrix[i] = (struct field_struct*) calloc(1,columns*sizeof(struct field_struct));
            }
    }
    
    int shID=shmget(5478,rows*columns*sizeof(struct field_struct,0666);
    float *myPtr;
    myPtr = shmat(shID, 0, 0);
    
    memcpy(myPtr,matrix,rows*columns*sizeof(struct field_struct));
    
    for (i=0; i<rows; i++)
          free(matrix[i]);
    free(matrix);
    Is this correct or is there a pointercasting missing?

    Alex

Popular pages Recent additions subscribe to a feed