Thread: Casting from a 1D array pointer to a scalar pointer

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    5

    Casting from a 1D array pointer to a scalar pointer

    Hi guys,

    I want to cast two pointers as follows:
    (with the assumption that the memory has properly been allocated to both integer pointers)

    insert
    Code:
    /* if the data stored in a are as follows */
    
    int (*a)[3] = {{2,1,3}, {3,4,7}};
    
    /* then I want to cast to an int scalar pointer */
    
    int *b = (int *) a;
    How are the data in b arranged ? (like this: {2, 1, 3, 3, 4, 7})

    In contrast, if I want to cast from b back to a, how are the data in a then arranged?


    Thank you in advance
    Komkamol

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I think you need to explain what you intend by this, since it is not legal C code, AFAIK:

    Code:
    int (*a)[3] = {{2,1,3}, {3,4,7}};
    Anyway, if you assign a pointer to another variable, the memory is not copied. If the first variable was a pointer, you simply have two pointers to the same chunk of memory, so nothing is "rearranged".
    Code:
    	int x = 25186;
    	char *y = (char*)&x;
    	printf("%c %c", y[0], y[1]);
    However, casting and type manipulation will affect how you access that memory. For example, the above, totally legal, code yields:

    b b

    Because a single int is (generally) 4 bytes, while a char is one, meaning four bytes fit into an int (and the first two bytes of the integer, 25186, are actually identical, as are the last two).
    Last edited by MK27; 09-24-2009 at 07:50 AM.
    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
    Sep 2009
    Posts
    5
    You are right that my code is illegal.

    This "a" pointer must be allocated with a dynamic memory of 2*sizeof(int [3]).
    I had already mentioned that the pointer had been properly memory-allocated so that
    I did not show this on my code. And I knew the code I wrote is illegal but I just wanted to tell
    you what the member values stored in the "a" variable are, so that someone could give me
    a concrete answer to this question with a concrete example.

    So, I will ask again.

    insert
    Code:
    int (*a)[3] = (int (*) [3])malloc(2*sizeof(int [3]));
    a[0][0] = 2;
    a[0][1] = 1;
    a[0][2] = 3;
    a[1][0] = 3;
    a[1][1] = 4;
    a[1][2] = 7;
    
    int *b = (int *)malloc(6*sizeof(int));
    
    b = (int *) a; /* what will happen at this position */
    Should the values accessed through "b" look like the following?:

    b[0] equal to 2
    b[1] equal to 1
    b[2] equal to 3
    b[3] equal to 3
    b[4] equal to 4
    b[5] equal to 7

    In contrast, if I have "b" as shown above and want to cast the variable b in the other way around as follows:

    insert
    Code:
    a = (int (*) [3]) b;
    Should the values accessed through "a" look like the following?:

    a[0][0] equal to 2
    a[0][1] equal to 1
    a[0][2] equal to 3
    a[1][0] equal to 3
    a[1][1] equal to 4
    a[1][2] equal to 7

    Thank you in advance
    Komkamol

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by komkamol View Post
    You are right that my code is illegal.

    This "a" pointer must be allocated with a dynamic memory of 2*sizeof(int [3]).
    I had already mentioned that the pointer had been properly memory-allocated so that
    I did not show this on my code. And I knew the code I wrote is illegal but I just wanted to tell
    you what the member values stored in the "a" variable are, so that someone could give me
    a concrete answer to this question with a concrete example.
    It is more than just the fact that it is illegal; it does not make sense, either. Well, I presume it does to you. This is slightly better but you still use these mysterious parentheses (in red) in your declaration:
    Code:
    int (*a)[3] = (int (*) [3])malloc(2*sizeof(int [3]));
    I think want you want should look more like this:
    Code:
    int a[2][3];
    Now, if you want to dynamically allocate all of the memory, you are looking at something much more complex:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ROWS 2
    #define COLS 3
    
    int main(void) {
    	int **a = malloc(ROWS*sizeof(int*)), 
    		nums[6] = { 2, 1, 3, 3, 4, 7 },
    		i, j, c=0;
    	
    	for (i=0;i<ROWS;i++) {
    		a[i] = malloc(COLS*sizeof(int));
    		for (j=0; j<COLS; j++) a[i][j] = nums[c++];
    	}
    	
    	printf("%d %d %d\n", a[0][1], a[0][0], a[1][0]);
    	return 0;
    }
    Notice it is not necessary to (cast*)malloc in C, and your attempt to include a multiplier in your cast (the green part above) is non-sensical.
    Last edited by MK27; 09-24-2009 at 10:36 AM.
    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
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    This is slightly better but you still use these mysterious parentheses (in red) in your declaration:
    That declares a pointer to an array of 3 ints, so they are not that mysterious.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    That declares a pointer to an array of 3 ints, so they are not that mysterious.
    Well I'll be darned. Sorry Komkamol. Still, I am almost positive that is not how you want to start, since an array of 3 ints cannot become a 2x3 matrix.
    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
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What
    Code:
    b = (int *)a;
    does in your code is leak memory, specifically the memory you had allocated to b (the second malloc call).

    If you want to copy things, you are looking for memcpy.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by komkamol View Post
    Code:
    b = (int *) a; /* what will happen at this position */
    This makes "b" point to the base address of "a" and the cast forces it to point to an int instead of an array of ints.
    Quote Originally Posted by komkamol View Post
    Code:
    int *b = (int *)malloc(6*sizeof(int));
    No need for the malloc() - leaks memory away.
    Quote Originally Posted by komkamol View Post
    Should the values accessed through "b" look like the following?:

    b[0] equal to 2
    b[1] equal to 1
    b[2] equal to 3
    b[3] equal to 3
    b[4] equal to 4
    b[5] equal to 7
    Yep that is correct.
    Quote Originally Posted by komkamol View Post
    In contrast, if I have "b" as shown above and want to cast the variable b in the other way around as follows:

    insert
    Code:
    a = (int (*) [3]) b;
    Should the values accessed through "a" look like the following?:

    a[0][0] equal to 2
    a[0][1] equal to 1
    a[0][2] equal to 3
    a[1][0] equal to 3
    a[1][1] equal to 4
    a[1][2] equal to 7

    Thank you in advance
    Komkamol
    Yep!
    Last edited by itCbitC; 09-24-2009 at 12:13 PM.

  9. #9
    Registered User
    Join Date
    Sep 2009
    Posts
    5
    Thanks a lot guys. I got the memory leakage issue you guys were trying to explain me.
    Can anyone here confirm that the answer "Mr. itCbitC" gave me is correct?

    Komkamol

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. Pointer with Multi-dimensional Array
    By whichet in forum C Programming
    Replies: 7
    Last Post: 11-28-2007, 12:26 AM
  3. Replies: 6
    Last Post: 11-09-2006, 03:28 AM
  4. 2D array pointer?
    By willc0de4food in forum C Programming
    Replies: 4
    Last Post: 04-23-2006, 08:16 AM
  5. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM