Thread: Ptr + byte gives offset + 3 ?

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    44

    Ptr + byte gives offset + 3 ?

    I want to create a distance of 1 byte between the pointers. So I don't get this debugging session where I'll get a distance of 3. Here's a image :

    http://i54.tinypic.com/2j0zby0.png

    Hopefully someone knows.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    A distance of 3? I don't know of any computer that does that...

    What exactly are you trying to do?
    Last edited by CommonTater; 09-01-2011 at 03:48 PM.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you haven't completely mucked up the types, then you want to just type " + k". Use pointer arithmetic to your advantage as opposed to working against it.

  4. #4
    Registered User
    Join Date
    Jul 2011
    Posts
    44
    But why the 3 ? Who can explain to me that ! I need to allign in memory to write it back to file.
    Last edited by lamko; 09-01-2011 at 03:48 PM.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Not without code, we don't. Or complete code I should say. Post all the relevant code, definitions and all, in code tags. We can't tell much without knowing the type of the variables used, since pointer arithmetic depends on that.

  6. #6
    Registered User
    Join Date
    Jul 2011
    Posts
    44
    Here's my code :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    typedef uint8_t  BYTE;
    typedef uint32_t DWORD;
    typedef int32_t  LONG;
    typedef uint16_t WORD;
    
    typedef struct
    {
        BYTE  rgbtBlue;
        BYTE  rgbtGreen;
        BYTE  rgbtRed;
    } __attribute__((__packed__))
    RGBTRIPLE;
    
    int main(void)
    {
    
        int k;
        int nrows = 5;     /* Both nrows and ncols could be evaluated */
        int ncols = 8;    /* or read in at run time */
    
        /* we now allocate the memory for the array */
    
        RGBTRIPLE *aptr = malloc(nrows * ncols * sizeof(RGBTRIPLE));
        if (aptr == NULL)
        {
            puts("\nFailure to allocate room for the array");
            exit(0);
        }
    
        /* next we allocate room for the pointers to the rows */
    
        RGBTRIPLE **rptr = malloc(nrows * sizeof(RGBTRIPLE *));
        if (rptr == NULL)
        {
            puts("\nFailure to allocate room for pointers");
            exit(0);
        }
    
        /* and now we 'point' the pointers */
    
        for (k = 0; k < nrows; k++)
        {
    
            rptr[k] = aptr + (k * sizeof(BYTE));    // sizeof(BYTE) * 3 = structure size
        }
    
        return 0;
    }

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    typedef uint8_t  BYTE;
    typedef uint32_t DWORD;
    typedef int32_t  LONG;
    typedef uint16_t WORD;
    Please, don't take a nice, standard type that everybody recognizes, and replace it with inaccurate, non-standard, ALL CAPS types that nobody knows. Think of the confusion between using "long", which is a signed long int, which is minimum 4 bytes, but maybe more, and LONG, an unsigned long it that is exactly 4 bytes. Just use uint8_t for your struct elements. Syntactic sugar, like real sugar, is bad for you.

    Code:
    typedef struct
    {
        BYTE  rgbtBlue;
        BYTE  rgbtGreen;
        BYTE  rgbtRed;
    } __attribute__((__packed__))
    RGBTRIPLE;
    
    int main(void)
    {
    
        int k;
        int nrows = 5;     /* Both nrows and ncols could be evaluated */
        int ncols = 8;    /* or read in at run time */
    
        /* we now allocate the memory for the array */
    
        RGBTRIPLE *aptr = malloc(nrows * ncols * sizeof(RGBTRIPLE));
        if (aptr == NULL)
        {
            puts("\nFailure to allocate room for the array");
            exit(0);
        }
    
        /* next we allocate room for the pointers to the rows */
    
        RGBTRIPLE **rptr = malloc(nrows * sizeof(RGBTRIPLE *));
        if (rptr == NULL)
        {
            puts("\nFailure to allocate room for pointers");
            exit(0);
        }
    
        /* and now we 'point' the pointers */
    
        for (k = 0; k < nrows; k++)
        {
    
            rptr[k] = aptr + (k * sizeof(BYTE));    // sizeof(BYTE) * 3 = structure size
        }
    
        return 0;
    }
    Right, aptr is an RGBTRIPLE pointer, and sizeof(RGBTRIPLE) is 3. That means aptr + 1 will give you an address 3 bytes after aptr, aptr + 2 is 6 bytes past aptr, etc. C is smart enough to scale the pointer arithmetic for you based on the size of what the pointer points to. But why not just use array notation? It's much cleaner:
    Code:
    rptr[k] = aptr[k];
    They're 100% equivalent.

    EDIT: I misinterpreted the code to be array assignment instead of making a 2-d array. Ignore the "use array notation" part.
    Last edited by anduril462; 09-01-2011 at 04:12 PM.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    rptr[k] = aptr + k*ncols;
    Last edited by tabstop; 09-01-2011 at 03:59 PM. Reason: forgot the [k]

  9. #9
    Registered User
    Join Date
    Jul 2011
    Posts
    44
    It's a two dimensional array Where do you guys think the structure gets saved in memory after seen te ptr values ?
    Last edited by lamko; 09-01-2011 at 04:06 PM.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The information is stored in the massive chunk of memory you allocated to aptr. You set the pointers in rptr to point into that memory.

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Sorry, I thought you were just copying arrays. I see now that you are making an array of arrays (array of pointers, technically). I thought we had this solved in your previous thread. What happend? What's wrong with:
    Code:
    RGBTRIPLE **image = malloc(rows * sizeof(*image));for (i = 0; i < rows; i++) {
        image[i] = malloc(cols * sizeof(*image[0]));
    }
    Just add a check after each malloc to make sure it succeeded, and free everything up if it failed.

  12. #12
    Registered User
    Join Date
    Jul 2011
    Posts
    44
    I wanted another try but now array's contents to be contiguous in memory. I'm surelly gone follow all your advice but this is pure me messing around with pointers.
    Last edited by lamko; 09-01-2011 at 04:21 PM.

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Okay, so that's why you've got the massive malloc; that's fine. Just remember (or learn, at some point) how pointer arithmetic works: the size of the objects pointed to is already "built in", so you don't want to do it yourself.

  14. #14
    Registered User
    Join Date
    Jul 2011
    Posts
    44
    I know that but I want to verify it's really working!
    rptr[k] = aptr + (k * sizeof(BYTE) * 3 * ncols);
    Where is the space it's using to save the struct ? Or how do I debug this to find it ?

  15. #15
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by lamko View Post
    I wanted another try but now array's contents to be contiguous in memory. I'm surelly gone follow all your advice but this is pure me messing around with pointers.
    Gotcha. If you want a contiguous block of memory, one that behaves just like a 2-d array, use this idiom:
    Code:
    RGBTRIPLE **image = malloc(rows * sizeof(*image));  // this is for the first (leftmost) index of the array
    image[0] = malloc(rows * cols * sizeof(*image[0]));  // this is for the actual array elements, all row x col of them
    for (i = 0; i < rows; i++) {
        image[i] = image[0] + i * cols;  // make the first index point to appropriate offsets in the contiguous block of memory
    }
    No need for rptr and aptr.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File Comparision byte by byte
    By anusha2489 in forum C Programming
    Replies: 12
    Last Post: 05-16-2011, 06:58 AM
  2. reading files byte by byte
    By cpsc in forum C++ Programming
    Replies: 12
    Last Post: 01-07-2011, 03:54 PM
  3. help! (int*)+offset
    By RobotGymnast in forum C++ Programming
    Replies: 6
    Last Post: 01-06-2008, 01:12 PM
  4. offset
    By Rhidian in forum C Programming
    Replies: 6
    Last Post: 04-14-2005, 08:57 AM
  5. Reading A Byte From A Certain Offset
    By 4point5 in forum Windows Programming
    Replies: 1
    Last Post: 10-31-2002, 06:36 PM