Thread: Why can't get the right address for char type

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Feb 2008
    Location
    China
    Posts
    28

    Unhappy Why can't get the right address for char type

    Hi friends,please help to see the following codes:
    Code:
    #include <iostream>
    using namespace std;
    int main(void)
    {
    	int a=4.5;
    	char b='c';
    	cout<<"The data "<<a<<" stores at address "<<&a<<endl;
    	cout<<"The data "<<b<<" stores at address "<<&b<<endl;
    	return 0;
    }
    I got the following result:
    /*
    The data 4 stores at address 0012FF60
    The data c stores at address c烫烫烫烫
    */
    Why can't I get the right address for b?
    I found the VC2005 compiler run the command:
    00411DA3 8D 4D EF lea ecx,[b]
    00411DA6 51 push ecx
    where ECX==0012FF57
    for &b but why shows the wrong result?

    Thanks a lot for any help.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by chenayang View Post
    Hi friends,please help to see the following codes:
    Code:
    #include <iostream>
    using namespace std;
    int main(void)
    {
    	int a=4.5;
    	char b='c';
    	cout<<"The data "<<a<<" stores at address "<<&a<<endl;
    	cout<<"The data "<<b<<" stores at address "<<&b<<endl;
    	return 0;
    }
    I got the following result:
    /*
    The data 4 stores at address 0012FF60
    The data c stores at address c烫烫烫烫
    */
    Why can't I get the right address for b?
    I found the VC2005 compiler run the command:
    00411DA3 8D 4D EF lea ecx,[b]
    00411DA6 51 push ecx
    where ECX==0012FF57
    for &b but why shows the wrong result?

    Thanks a lot for any help.
    That's because the stream output (e.g. cout <<) of a char * is interpreted to be a string to be printed, not an integer value. If you cast it to void *, like this:

    Code:
    	cout<<"The data "<<b<<" stores at address "<<(void *)&b<<endl;
    it should do what you want.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Feb 2008
    Location
    China
    Posts
    28
    Got it.thanks,Mats.
    But where can I get this info. in other files/books?

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by chenayang View Post
    Got it.thanks,Mats.
    But where can I get this info. in other files/books?
    Good question. I personally just figured it out based on the fact that cout will print a char * as a string in general, and &b, where b is a char becomes a char *, so it will attempt to print a string rather than the value of the pointer. The natural consequence is to cast the pointer to some time that doesn't become a string - void * is a pointer type that any other pointer can be cast to - along with it not needing to be any other pointer type, so it's a good choice.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Feb 2008
    Location
    China
    Posts
    28
    Thanks,Mats.
    I found the referenced notes in C++ Primer 5th.Edition as well. "char *" is just a special condition and cout treat it as a string pointer.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Char* is pretty much a special type all around. C functions uses it all the time to represent a string (and C++ functions that accept char* too). So be careful with it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    Does every platform or compiler supports a pointer to void? I cannot find the source, but I have read that this is not the case.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    That would be strange, seeing as that any pointer used by the processor (or rather, address) would be void*. The processor isn't aware of any type - it's just data, so void* should exist anywhere.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    That would be strange, seeing as that any pointer used by the processor (or rather, address) would be void*. The processor isn't aware of any type - it's just data, so void* should exist anywhere.
    That's not entirely true on all processor types. Some have "split pointers", where a pointer actually contains a word address, and then some extra portion elsewhere (another register or such) contains "byte within word". These are of course not your common x86, Sparc, Mips, Arm, Alpha, Vax, 68K, 29K or such, but some less common (but still important) processors do support this.

    As to void being supported by all compilers, yes, if we count reasonably modern compilers. Compilers before ANSI didn't have void, it was a char. So in some really old code, you may find something like:
    #ifdef something
    #define void char
    #endif

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Banned
    Join Date
    May 2008
    Location
    Four Dots Planet
    Posts
    72
    Quote Originally Posted by chenayang View Post
    Hi friends,please help to see the following codes:
    Code:
    #include <iostream>
    using namespace std;
    int main(void)
    {
    	int a=4.5;
    	char b='c';
    	cout<<"The data "<<a<<" stores at address "<<&a<<endl;
    	cout<<"The data "<<b<<" stores at address "<<&b<<endl;
    	return 0;
    }
    I got the following result:
    /*
    The data 4 stores at address 0012FF60
    The data c stores at address c烫烫烫烫
    */
    Why can't I get the right address for b?
    I found the VC2005 compiler run the command:
    00411DA3 8D 4D EF lea ecx,[b]
    00411DA6 51 push ecx
    where ECX==0012FF57
    for &b but why shows the wrong result?

    Thanks a lot for any help.
    i wonder besides giving wrong results why this did not produce a runtime segment fault error the cout will assume it char* and will go on printing chars from the address unless it sees a '\0' char somewhere but good to know that printing char address is not straight forward my version would be
    Code:
    cout << static_cast<void*>(&b) << endl;

  11. #11
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    standard does not guarantee a segfault for out of bound access.

    try this:
    Code:
    int main() {
         int a[10];
         a[12] = 10;
    }
    On my Linux it doesn't segfault. Accessing out of bound is undefined behaviour - anything could happen. It could work perfectly, it could segfault, it could make your head explode...

  12. #12
    Banned
    Join Date
    May 2008
    Location
    Four Dots Planet
    Posts
    72
    change a[12] to a[12*1024] you will get a segmentation fault and i am sick of the convenience word undefined used so sporadically by the c++ standard and this really makes my head \eXplode/

  13. #13
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by (::) View Post
    change a[12] to a[12*1024] you will get a segmentation fault
    How about on a system without protected memory?

    Or in the case where you actually own the memory at that location?

    Quote Originally Posted by (::) View Post
    and i am sick of the convenience word undefined used so sporadically by the c++ standard and this really makes my head \eXplode/
    It's not there for convenience.

  14. #14
    Banned
    Join Date
    May 2008
    Location
    Four Dots Planet
    Posts
    72
    windows mac and linux have protected memory you are working on dos still?

    it is for their convenience not ours that they used undefined instead of taking time to define some useful behavior.

  15. #15
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by (::) View Post
    windows mac and linux have protected memory you are working on dos still?
    As someone pointed out, there are systems that are not always able to provide you with memory protection since you might technically own all memory.

    And you still missed the point where I said you could still own the memory you accidentally access. Even on Windows, I can corrupt my program's variables by writing past the end of an array and the program could appear to run properly.

    Quote Originally Posted by (::) View Post
    it is for their convenience not ours that they used undefined instead of taking time to define some useful behavior.
    You're displaying horrible ignorance here, in addition to mixing up the responsibilities of the hardware, software, and languages.

    Language standards like those for C and C++ left many things undefined so as not to restrict the language for the type of hardware and OS that it may be used in conjunction with. In other words, if C++ demands bounds checking, but the hardware is not capable of it, or the OS doesn't take advantage of such ability in the hardware, then by nature C++ functionality is broken on this particular system.

    And for that matter, why do you need a system to check boundaries in this manner to be guarenteed as part of the language? You already know that for all intents and purposes, if you access memory out of bounds, that means you messed up as a programmer, and furthermore, your program is not correct. This is why it is left as being undefined. This way, various systems that have the ability to provided these features can provide it, while those that can't can still support C++.

    There is a lot more to consider than just complaining about bounds checking not being inherent in C++. You could always try to use some sort of class of a data structure that will protect you from yourself, but for pure arrays, this is something beyond what C++ was technically designed for.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Conversion of pointers to functions
    By hzmonte in forum C Programming
    Replies: 0
    Last Post: 01-20-2009, 01:56 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM