Thread: I thought pointers were pointers...

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    81

    I thought pointers were pointers...

    Why is the size of c being read as the size of a 32bit pointer instead of the size of the buffer it points to? What is different about the pointers?

    Code:
    #include <stdio.h>
    
    int main() {
      
      char  a[] = "kiera";
      char  b[69] = "kiera haha";
      char* c = "keira rules";
    
      printf("a = &#37;d, b = %d, c = %d c_string = %s\n", sizeof(a), sizeof(b), sizeof(c), c);
      return 0;
    }
    
    /** OUTPUT **
     *
     * a = 6, b = 69, c = 4, c_string = "keira rules"
     *
     */

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Because c is a pointer and the size of a pointer is the size of the pointer and not the size(length) of the data it happens to point to. a and b are character arrays and therefore the size returned is the length of those arrays. If you wanted the length of the data pointed to by c to be output you'd have to print the return value of strlen(c).
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    Registered User
    Join Date
    Jul 2006
    Posts
    162
    i misunderstood...
    Last edited by simpleid; 08-15-2007 at 07:52 AM.

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    81
    think about data as vertically aligned arrays [ this->(| | | |) not this-> (-- -- -- --) ], size is the height of this conceptual data model and length is its vector... coincidentally vectors are the names of dynamic arrays! hah...

    so 32 bit value is "height" (size), 10 items in an array its "length" (vector).
    That's pretty confusing... I'm pretty sure that in memory a character array is stored as contiguous bytes, and the pointer could be anywhere in memory and points to the first byte of that array. So what you said doesn't seem pertinent.

    Also, I don't think you guys understand what I'm asking. I'm asking how does sizeof() know the lengths of the buffers allocated with the syntax char buffer[length], and not the syntax char* buffer = "some string".

    Personally, I think the reason is that sizeof is kind of like a preprocessor directive. I don't think there is a difference between the pointers at all, but the sizeof() command sees the pointers as different because of how they were declared. Could someone explain more?

  5. #5
    Registered User
    Join Date
    Jul 2006
    Posts
    162
    keira, i didn't say that memory wasn't stored as contiguous bytes did i? i told you to imagine something to sort out two aspects, length and size. but i misunderstood your problem to begin with so never mind what i said.

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by keira View Post
    Personally, I think the reason is that sizeof is kind of like a preprocessor directive. I don't think there is a difference between the pointers at all, but the sizeof() command sees the pointers as different because of how they were declared. Could someone explain more?
    I don't know how I can say it other than: a and b are not pointers, they are arrays. sizeof an array is the length of the array, sizeof a pointer is the size of the pointer and not the length of the data being pointed to. sizeof is a unary operator and not a preprocessor directive.

    See: http://en.wikipedia.org/wiki/Sizeof
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Registered User
    Join Date
    Jul 2006
    Posts
    162
    i'm curious...

    how exactly does a computer manage an "array"?

    int hi[5], is the 5 stored somewhere in memory? and the the fact that "5" points to an int stored somewhere? and then what value each 5 int's point to contained by "hi"? how is all this information managed by only 1 keyword to reference the information, via "hi" ?

    int is what, 32bit value, and 5 of them, so the computer allocates 5*32 bits of space right?, so then how is the information about the array stored in memory?

    i'm a little confused... it seems that declaring an array is actually something like... an obscure data type.

    how does an array -actually- work... ? or am i over thinking it?

    or since you declare int, it just picks up every 32bit value, puts it in to an int for you, but how does the program know there's a const value attached to it (the size of the array declared)?

    can this value be mapped to the array name via some other variable? and can this be a work around for passing arrays through functions without needing two inputs, a pointer to the first item and size?
    Last edited by simpleid; 08-15-2007 at 09:47 AM.

  8. #8
    System Novice siavoshkc's Avatar
    Join Date
    Jan 2006
    Location
    Tehran
    Posts
    1,246
    For a static array:
    Code:
    int myArr[20];
    Address of myArr is the first item of 20 sequential items in memory. (myArr + 2) is address of the third item and so on. myArr[1] is equal to *(myArr + 1) so it is the second item.

    For a pointer
    Code:
    int* myPtr = new int[20];
    myPtr points to the first item of 20 sequential items in memory. Note that myPtr has an address, but we don't need it. myPtr[1] is equal to *(myPtr + 1) means the second item.

    You can see that pointer and array are used in the same way. But remember that they are completely different.

    int is what, 32bit value, and 5 of them, so the computer allocates 5*32 bits of space right?, so then how is the information about the array stored in memory?
    It will be strored as 5 int after each other. Means 5*32 bits.

    Compiler knows the size of each array item. So for myArr[3] it will be myArr + 3 * sizeof(int) and means forth item.
    int hi[5], is the 5 stored somewhere in memory?
    5 is not stored anywhere.
    Learn C++ (C++ Books, C Books, FAQ, Forum Search)
    Code painter latest version on sourceforge DOWNLOAD NOW!
    Download FSB Data Integrity Tester.
    Siavosh K C

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    It just increases the stack size (for local automatic arrays) by sizeof(*array) * size bytes. If it's a char array, sizeof(*array) will be 1 (the size of one element of the array). If it's an int array, sizeof(*array) will be 4 (for 32-bit ints). The actual size of the array isn't stored in the executable or memory anywhere.

    I don't see why you'd think a bunch of information about the array would need to be stored anywhere. During compile time, the compiler knows the type of array, so it can handle all the memory adjustments it needs to. The executable just simply moves around in memory according to the instructions the compiler laid out. The finished executable doesn't even know an array existed. It just knows "I need to go to this memory location".
    If you understand what you're doing, you're not learning anything.

  10. #10
    System Novice siavoshkc's Avatar
    Join Date
    Jan 2006
    Location
    Tehran
    Posts
    1,246
    You can also read this in cplusplus in my articles. And here is another:
    The question is "Are these two statements equal?"
    Code:
    int var[20];
    int *var = new int[20];
    I think it is obvious that they are not! First one is a static array and the second one is a dynamic array and a pointer that points to it.
    So why we can use these two statement for both?
    Code:
    var[12];
    *(var + 12);
    Because C/C++ lets you to do so. But the mechanism to calculate effective address is a little bit different. For static array: executive file knows the address of var[0] and knows the size of each array element. So Effective Address = Address of var[0] + (12 * sizeof(var[0]) )

    But for the pointer and dynamic array: executive file does not know the address of the dynamic array's first element (var[0]) in the memory. But it knows the address of a pointer (pointer is a variable that holds a memory address) that points to the first element of the dynamic array. The formula for calculating effective address is:
    Effective Address = Address of var[0] + (12 * sizeof(var[0]) )

    So where is the difference? It is in getting address of var[0].

    In the case of pointer, Executive file does not know the address of var[0], it needs to look into the pointer to find that address. Look at the assembly codes for int a = var[12]:
    For static array:
    Code:
    	 mov         eax,dword ptr [ebp-20h]	//20h = 32 
    	 mov         dword ptr [ebp-54h],eax	//54h = 84
    For dynamic array:
    Code:
    	 mov         eax,dword ptr [ebp-4] 
    	 mov         ecx,dword ptr [eax+30h] //30h = 48
    	 mov         dword ptr [ebp-8],ecx
    ebp is the start of stack and have the value of 1245040. The stack will be filled like the picture:<<>>

    In our example program we have only one array and a variable 'a' in the stack. The first element of array is placed in the address ebp – 80 = ebp - (4 * 20) (Each integer is four bytes and the array has twenty elements) address of variable 'a' is ebp - "size of the whole array" - "size of int" = ebp - 80 – 4 = ebp - 84

    For calculating address of var[12] we should subtract 48 from 80 that gives 32 and then minus it from ebp. So it is ebp – 32.

    [] means "the value that this address points to" it is like dereferencing sign in C/C++ (astrix "*").
    First line says place the value which is placed in memory address "ebp - 32" in the eax register (Registers are some small memories in the CPU used for proccessing operations).

    Now we have var[12] in eax. Then it moves it into variable 'a': In the second line as it says place the value of eax in the memory address "ebp - 84" which is the address of 'a' as we calculated above.

    Now for the dynamic array case 'a' and 'var' are two local variables placed in the stack both are 32 bits (= 4 bytes). 'a' is an integer and 'var' is a pointer. In my compiler int is four bytes and in my machine pointers are 4 bytes too.

    The var is the first variable in the stack. Its address is "ebp - 4". The 'a' is placed right after it so has the address "ebp – 8". In the first line, it picks the value of the var (ebp - 4) which is the address of allocated memory returned by new operator. Then puts the address in eax register. After this it needs the value of var[12]. To calculate its address, it adds 48 to eax. Which means adding 48 (= 4 * 12) to address of allocated memory ([ebp - 4]). In the second line it puts the value of var[12] in ecx register. At last in the third line it puts the value of ecx in the 'a' (which has the address ebp - 8).

    You may ask why in the case of static array it subtract the offset from base address while for dynamic array it adds the offset to base address. Well, this is because of the way that stack and heap memory are managed and is out of scope.

    The static arrays are placed in the stack portion of memory while dynamic arrays are in the heap portion.
    Learn C++ (C++ Books, C Books, FAQ, Forum Search)
    Code painter latest version on sourceforge DOWNLOAD NOW!
    Download FSB Data Integrity Tester.
    Siavosh K C

  11. #11
    Registered User
    Join Date
    Aug 2007
    Posts
    81
    I don't know how I can say it other than: a and b are not pointers, they are arrays
    I disagree. a and b are pointers. Arrays are an abstract concept unbeknownst to the instruction set. If the compiler treats a and b differently from c, than that is it's own prerogative, however, c IS THE SAME AS A AND B. (lol sorry for yelling but slavosh started it!)

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    a and b are arrays.
    http://c-faq.com/aryptr/index.html

    > however, c IS THE SAME AS A AND B.
    No they're not.
    c = a;
    is allowed.
    a = c;
    is not.

    Also, the different answers for sizeof tell you that they have to be different.

    There are a couple of really important exceptions to the "arrays just become pointers to the first element" rule, as explained by the c.l.c FAQ.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I disagree. a and b are pointers. Arrays are an abstract concept unbeknownst to the instruction set. If the compiler treats a and b differently from c, than that is it's own prerogative, however, c IS THE SAME AS A AND B.
    However, this is not machine language or assembly language. This is C. Arrays are a programming concept present in C. As such, a and b are arrays, not pointers.
    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

  14. #14
    Registered User
    Join Date
    Aug 2007
    Posts
    81
    Does this differ in C++? In C++ are arrays not glorified pointers?

    To demonstrate:

    Code:
    #include <iostream>
    
    int main() {
      char pointer[] = "keira";
      char*  otherPointer = pointer;
      std::cout << otherPointer << std::endl;
      return 0;
    }
    /** OUTPUT ** 
     *
     * keira 
     * 
     */
    Last edited by keira; 08-15-2007 at 10:45 AM.

  15. #15
    Registered User
    Join Date
    Aug 2007
    Posts
    81
    Because C/C++ lets you to do so. But the mechanism to calculate effective address is a little bit different. For static array: executive file knows the address of var[0] and knows the size of each array element. So Effective Address = Address of var[0] + (12 * sizeof(var[0]) )

    But for the pointer and dynamic array: executive file does not know the address of the dynamic array's first element (var[0]) in the memory. But it knows the address of a pointer (pointer is a variable that holds a memory address) that points to the first element of the dynamic array. The formula for calculating effective address is:
    Effective Address = Address of var[0] + (12 * sizeof(var[0]) )

    So where is the difference? It is in getting address of var[0].

    In the case of pointer, Executive file does not know the address of var[0], it needs to look into the pointer to find that address. Look at the assembly codes for int a = var[12]:
    For static array:
    Code:

    mov eax,dword ptr [ebp-20h] //20h = 32
    mov dword ptr [ebp-54h],eax //54h = 84

    For dynamic array:
    Code:

    mov eax,dword ptr [ebp-4]
    mov ecx,dword ptr [eax+30h] //30h = 48
    mov dword ptr [ebp-8],ecx

    ebp is the start of stack and have the value of 1245040. The stack will be filled like the picture:<<>>

    In our example program we have only one array and a variable 'a' in the stack. The first element of array is placed in the address ebp – 80 = ebp - (4 * 20) (Each integer is four bytes and the array has twenty elements) address of variable 'a' is ebp - "size of the whole array" - "size of int" = ebp - 80 – 4 = ebp - 84

    For calculating address of var[12] we should subtract 48 from 80 that gives 32 and then minus it from ebp. So it is ebp – 32.

    [] means "the value that this address points to" it is like dereferencing sign in C/C++ (astrix "*").
    First line says place the value which is placed in memory address "ebp - 32" in the eax register (Registers are some small memories in the CPU used for proccessing operations).

    Now we have var[12] in eax. Then it moves it into variable 'a': In the second line as it says place the value of eax in the memory address "ebp - 84" which is the address of 'a' as we calculated above.

    Now for the dynamic array case 'a' and 'var' are two local variables placed in the stack both are 32 bits (= 4 bytes). 'a' is an integer and 'var' is a pointer. In my compiler int is four bytes and in my machine pointers are 4 bytes too.

    The var is the first variable in the stack. Its address is "ebp - 4". The 'a' is placed right after it so has the address "ebp – 8". In the first line, it picks the value of the var (ebp - 4) which is the address of allocated memory returned by new operator. Then puts the address in eax register. After this it needs the value of var[12]. To calculate its address, it adds 48 to eax. Which means adding 48 (= 4 * 12) to address of allocated memory ([ebp - 4]). In the second line it puts the value of var[12] in ecx register. At last in the third line it puts the value of ecx in the 'a' (which has the address ebp - 8).

    You may ask why in the case of static array it subtract the offset from base address while for dynamic array it adds the offset to base address. Well, this is because of the way that stack and heap memory are managed and is out of scope.

    The static arrays are placed in the stack portion of memory while dynamic arrays are in the heap portion.
    I don't understand where you got the idea that I was comparing dynamically allocated memory with local memory...

    I am simply saying that 4 bytes of memory whose value is an address that is the first element of what we call an array is the same thing as a pointer.

    I didn't know the C compiler treated arrays differently and I will look into that, thanks guys.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. 2D Array of Pointers
    By Slavakion in forum C++ Programming
    Replies: 12
    Last Post: 03-31-2004, 05:05 PM
  3. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM
  4. moving pointers to pointers
    By Benzakhar in forum C++ Programming
    Replies: 9
    Last Post: 12-27-2003, 08:30 AM
  5. Array of pointers
    By falconetti in forum C Programming
    Replies: 5
    Last Post: 01-11-2002, 07:26 PM