Thread: Pointer's

  1. #1
    Registered User
    Join Date
    Dec 2001
    Posts
    227

    Pointer's

    I kinda understand pointers after reading and reading... i know that pointers allocate memory spaces for type blah.. etc

    but.. there is one thing that i dont understad..
    why is it that on some codes that see, have something like

    Code:
    char *i;
    
      i = ( char * ) malloc( 50 * sizeof( char ));
    from what i know.. malloc allocate's memory space as well... This is confusing me a bit.. but heh i will keep reading.. maybe there is something that will hit the jackpot
    Only the strong survives.

  2. #2
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    i know that pointers allocate memory spaces
    Er, actually pointers store addresses of memory spaces.

    Code:
    char *i;
    This declares a pointer variable, a pointer-to-char.
    It can be used to store the address of a char.
    However, no new char has been created yet.

    Code:
     i = ( char * ) malloc( 50 * sizeof( char ));
    This actually creates the memory for new char and returns its address, which is stored in the pointer-to-char i.

  3. #3
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    the above is exactly right but I want to add something
    the prototype for malloc looks like this:
    Code:
    void* malloc(int bytes);
    now pointers are in fact typeless. They can point to anytype quite easily, especially since all they really are is integers and these integers correspond to a memory address.
    However to make a pointer of one type point to an object of another type you need to cast the pointer.

    Remember:
    Code:
    void* /* yes it's possible! */
    int*
    char*
    double*
    ...
    they can all be casted from each other to each other (though it gets a little dangerous if you don't know what you're doing).

    to cast a pointer to a different pointer type use the regular casting operator (type) object_to_be_casted

    since malloc returns a pointer to the amount of memory you requested but it doesn't know the type you wanted it just returns a pointer to an undefined type (void) so you have to cast the pointer to what you wanted:
    Code:
    char* myString;
    myString = (char*) malloc(sizeof(char)*3);
    strcpy(myString,"hi");
    /* code here  */
    free(myString); /* VERY IMPORTANT */
    in the above (line-by-line)
    I first initialized a new pointer, and it points to a character. And it just so happens that the character it points to can be chained together to form a string as long as it finally ends with '\0' *NULL*
    the second line calls malloc to allocate 3 characters, but to make sure that the proper space is allocated for a CHARACTER we multiply 3 by the size that a character takes up. I.E. sizeof(char)*3
    The third line is a function from string.h that copies the string in the second parameter to the first parameter.
    The fourth line unallocates the memory that malloc first allocated. this is VERY important otherwise after the program finishes the memory you allocated will stay there until you turn the computer off, and that hogs up memory that you might need later. This is known as a memory leak.

    also make sure you use free before changing the pointer at all. You can change the object itself that the pointer points to but don't change the pointer. Don't set it to null, don't point it to something else and don't do ANYTHING until you free() it.


    -LC
    Last edited by Lynux-Penguin; 10-11-2003 at 11:47 PM.
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  4. #4
    ~viaxd() viaxd's Avatar
    Join Date
    Aug 2003
    Posts
    246
    Originally posted by Lynux-Penguin

    The fourth line unallocates the memory that malloc first allocated. this is VERY important otherwise after the program finishes the memory you allocated will stay there until you turn the computer off, and that hogs up memory that you might need later. This is known as a memory leak.

    also make sure you use free before changing the pointer at all. You can change the object itself that the pointer points to but don't change the pointer. Don't set it to null, don't point it to something else and don't do ANYTHING until you free() it.

    http://www.eskimo.com/~scs/cclass/notes/sx11b.html
    Freeing unused memory is a good idea, but it's not mandatory. When your program exits, any memory which it has allocated but not freed should be automatically released. If your computer were to somehow ``lose'' memory just because your program forgot to free it, that would indicate a problem or deficiency in your operating system

  5. #5
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    im sorry to say but that is 100% wrong.

    C does NOT have a garbage collector. And the OS is not responsible for memory unallocated.

    The program gets the memory by using malloc which asks the OS for some memory in the heap and the OS tells it where it can get it and then malloc relays that info to your program. If your program never tells the OS that it is once again free for use, no matter what OS, it will not free it unless specified outside by maybe a cleaner or something. Otherwise the OS does NOT free it. What if you had a multiprocess program? And the processes shared a common bit of memory in the heap, are you saying as soon as one process is done the OS unallocates the memory? Nope, sorry.

    What you are referring to is known as a Garbage collector and it is usually done by either the compiler or done by an interepter that runs the program, the OS NEVER unallocates memory unless told to.

    -LC
    Last edited by Lynux-Penguin; 10-12-2003 at 02:17 AM.
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  6. #6
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    if you don't believe me run this program on any windows C/C++ compiler.

    Code:
    /*****************************************************************
     *  EXAMPLE  1                                                   *
     *  This simple program illustrates the basic debugging features *
     *  of the C runtime libraries, and the kind of debug output     *
     *  that these features generate.                                *
     *****************************************************************/
    
    #include <stdio.h>
    #include <string.h>
    #include <malloc.h>
    #include <crtdbg.h>
    
    // This routine place comments at the head of a section of debug output
    void OutputHeading( const char * explanation )
    {
       _RPT1( _CRT_WARN, "\n\n%s:\n**************************************\
    ************************************\n", explanation );
    }
    
    // The following macros set and clear, respectively, given bits
    // of the C runtime library debug flag, as specified by a bitmask.
    #ifdef   _DEBUG
    #define  SET_CRT_DEBUG_FIELD(a) \
                _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
    #define  CLEAR_CRT_DEBUG_FIELD(a) \
                _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
    #else
    #define  SET_CRT_DEBUG_FIELD(a)   ((void) 0)
    #define  CLEAR_CRT_DEBUG_FIELD(a) ((void) 0)
    #endif
    
    
    int main( )
    {
       char *p1, *p2;
       _CrtMemState s1, s2, s3;
    
       // Send all reports to STDOUT
       _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
       _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
       _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
       _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
       _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
       _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
    
       // Allocate 2 memory blocks and store a string in each
       p1 = malloc( 34 );
       strcpy( p1, "This is the p1 string (34 bytes)." );
    
       p2 = malloc( 34 );
       strcpy( p2, "This is the p2 string (34 bytes)." );
    
    
       OutputHeading( 
          "Use _ASSERTE to check that the two strings are identical" );
       _ASSERTE( strcmp( p1, p2 ) == 0 );
    
       OutputHeading( 
          "Use a _RPT macro to report the string contents as a warning" );
       _RPT2( _CRT_WARN, "p1 points to '%s' and \np2 points to '%s'\n", p1, p2 );
    
       OutputHeading( 
          "Use _CRTMemDumpAllObjectsSince to check the p1 and p2 allocations" );
       _CrtMemDumpAllObjectsSince( NULL );
    
       free( p2 );
    
       OutputHeading( 
          "Having freed p2, dump allocation information about p1 only" );
       _CrtMemDumpAllObjectsSince( NULL );
    
       // Store a memory checkpoint in the s1 memory-state structure
       _CrtMemCheckpoint( &s1 );
    
       // Allocate another block, pointed to by p2
       p2 = malloc( 38 );
       strcpy( p2, "This new p2 string occupies 38 bytes.");
    
       // Store a 2nd memory checkpoint in s2
       _CrtMemCheckpoint( &s2 );
    
       OutputHeading( 
          "Dump the changes that occurred between two memory checkpoints" );
       if ( _CrtMemDifference( &s3, &s1, &s2 ) )
          _CrtMemDumpStatistics( &s3 );
    
       // Free p2 again and store a new memory checkpoint in s2
       free( p2 );
       _CrtMemCheckpoint( &s2 );
    
       OutputHeading( 
          "Now the memory state at the two checkpoints is the same" );
       if ( _CrtMemDifference( &s3, &s1, &s2 ) )
          _CrtMemDumpStatistics( &s3 );
    
       strcpy( p1, "This new p1 string is over 34 bytes" );
       OutputHeading( "Free p1 after overwriting the end of the allocation" );
       free( p1 );
    
       // Set the debug-heap flag so that freed blocks are kept on the
       // linked list, to catch any inadvertent use of freed memory
       SET_CRT_DEBUG_FIELD( _CRTDBG_DELAY_FREE_MEM_DF );
    
       p1 = malloc( 10 );
       free( p1 );
       strcpy( p1, "Oops" );
    
       OutputHeading( "Perform a memory check after corrupting freed memory" );
       _CrtCheckMemory( );
    
       // Use explicit calls to _malloc_dbg to save file name and line number
       // information, and also to allocate Client type blocks for tracking
       p1 = _malloc_dbg( 40, _NORMAL_BLOCK, __FILE__, __LINE__ );
       p2 = _malloc_dbg( 40, _CLIENT_BLOCK, __FILE__, __LINE__ );
       strcpy( p1, "p1 points to a Normal allocation block" );
       strcpy( p2, "p2 points to a Client allocation block" );
    
       // You must use _free_dbg to free a Client block
       OutputHeading( 
          "Using free( ) to free a Client block causes an assertion failure" );
       free( p1 );
       free( p2 );
    
       p1 = malloc( 10 );
       OutputHeading( "Examine outstanding allocations (dump memory leaks)" );
       _CrtDumpMemoryLeaks( );
    
       // Set the debug-heap flag so that memory leaks are reported when
       // the process terminates. Then, exit.
       OutputHeading( "Program exits without freeing a memory block" );
       SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF );
      return 0;
    }
    CDTDBG is a library designed to CATCH but not FIX memory leaks. It will find it, show info about it but it will NOT unallocate it. Again nothing can unallocate the memory unless your program or another program does. And since all this does is keep track of what you have allocated it and compare it to the things you have unallocated and then display the differences (i.e. potential memory leaks)

    btw: here is the output if you can't run it on windows:
    Code:
    Use _ASSERTE to check that the two strings are identical:
    **************************************************************************
    C:\DEV\EXAMPLE1.C(56) : Assertion failed: strcmp( p1, p2 ) == 0
    
    
    Use a _RPT macro to report the string contents as a warning:
    **************************************************************************
    p1 points to 'This is the p1 string (34 bytes).' and 
    p2 points to 'This is the p2 string (34 bytes).'
    
    
    Use _CRTMemDumpAllObjectsSince to check the p1 and p2 allocations:
    **************************************************************************
    Dumping objects ->
    {13} normal block at 0x00660B5C, 34 bytes long
     Data: <This is the p2 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 32 20 73 
    {12} normal block at 0x00660B10, 34 bytes long
     Data: <This is the p1 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 31 20 73 
    Object dump complete.
    
    
    Having freed p2, dump allocation information about p1 only:
    **************************************************************************
    Dumping objects ->
    {12} normal block at 0x00660B10, 34 bytes long
     Data: <This is the p1 s> 54 68 69 73 20 69 73 20 74 68 65 20 70 31 20 73 
    Object dump complete.
    
    
    Dump the changes that occurred between two memory checkpoints:
    **************************************************************************
    0 bytes in 0 Free Blocks.
    38 bytes in 1 Normal Blocks.
    0 bytes in 0 CRT Blocks.
    0 bytes in 0 IgnoreClient Blocks.
    0 bytes in 0 (null) Blocks.
    Largest number used: 4 bytes.
    Total allocations: 38 bytes.
    
    
    Now the memory state at the two checkpoints is the same:
    **************************************************************************
    
    
    Free p1 after overwriting the end of the allocation:
    **************************************************************************
    memory check error at 0x00660B32 = 0x73, should be 0xFD.
    memory check error at 0x00660B33 = 0x00, should be 0xFD.
    DAMAGE: after Normal block (#12) at 0x00660B10.
    
    
    Perform a memory check after corrupting freed memory:
    **************************************************************************
    memory check error at 0x00660B10 = 0x4F, should be 0xDD.
    memory check error at 0x00660B11 = 0x6F, should be 0xDD.
    memory check error at 0x00660B12 = 0x70, should be 0xDD.
    memory check error at 0x00660B13 = 0x73, should be 0xDD.
    memory check error at 0x00660B14 = 0x00, should be 0xDD.
    DAMAGE: on top of Free block at 0x00660B10.
    DAMAGED located at 0x00660B10 is 10 bytes long.
    
    
    Using free( ) to free a Client block causes an assertion failure:
    **************************************************************************
    dbgheap.c(1039) : Assertion failed: pHead->nBlockUse == nBlockUse
    
    
    Examine outstanding allocations (dump memory leaks):
    **************************************************************************
    Detected memory leaks!
    Dumping objects ->
    {18} normal block at 0x00660BE4, 10 bytes long
     Data: <          > CD CD CD CD CD CD CD CD CD CD 
    Object dump complete.
    
    
    Program exits without freeing a memory block:
    **************************************************************************
    Detected memory leaks!
    Dumping objects ->
    {18} normal block at 0x00660BE4, 10 bytes long
     Data: <          > CD CD CD CD CD CD CD CD CD CD 
    Object dump complete.
    -LC
    Last edited by Lynux-Penguin; 10-12-2003 at 02:29 AM.
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  7. #7
    ~viaxd() viaxd's Avatar
    Join Date
    Aug 2003
    Posts
    246
    thanks a lot for explaining

  8. #8
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by Lynux-Penguin
    the above is exactly right but I want to add something
    ...
    now pointers are in fact typeless.
    My addition to the above:
    The pointer itself might be seen as typeless, but when you create a pointer using:
    char *pVal;
    the pointer is a character pointer. The pointer must know what it is pointing at, otherwise when you use pVal++ the compiler won't know what to add to the current value of the pointer, 1 for char, 4 for long, 8 for double, etc.

    I guess I'm saying that although it may be true that pointers are typeless, it's a confusing and unneccessary fact. The important thing to realize is that the pointer points to a memory location that does (usually) have a type.



    the prototype for malloc looks like this:
    Code:
    void* malloc(int bytes);
    ...
    since malloc returns a pointer to the amount of memory you requested but it doesn't know the type you wanted it just returns a pointer to an undefined type (void) so you have to cast the pointer to what you wanted:
    Code:
    char* myString;
    myString = (char*) malloc(sizeof(char)*3);
    ...
    Not quite. When you create a pointer using:
    char *pVal;
    the pointer is a character pointer. And because malloc() is defined as a void*, you do not have to cast it into the char*. Simply use
    Code:
    char* myString;
    myString = malloc(sizeof(char)*3);
    Void* pointers can be assigned to any pointer without the cast. I just wrote this test program:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        char *pChar;
        int  *pIntt;
        void *pVoid;
        
        pVoid = malloc(20);
        pChar = pVoid;
        pIntt = pVoid;
        
        pChar[0] = 0x03;
        pChar[1] = 0x07;
        pChar[2] = 0x0F;
        pChar[3] = 0x17;
        
        printf("pChar: %02x %02x %02x %02x \n", pChar[0], pChar[1], pChar[2], pChar[3]);
        printf("pIntt: %02x \n", pIntt[0]);
    
        pIntt = pChar;
        printf("pIntt: %02x \n", pIntt[0]);
    
        free(pVoid);
        return 0;
    }
    and recieved a suspicious pointer conversion warning on line:
    pIntt = pChar;
    This was the only warning, showing me that void* is assignable without cast. Borland 5.5
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  9. #9
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    most compilers probably will cast automatically without argument but in older times (i guess) you had to cast it. My compiler automatically does the cast but it is better to show the cast. I forgot exactly why.

    But I do believe that it is better to actually cast it rather than have the compiler cast it.

    he's right tho.
    Pointers are basically ints. But their type resides in the type they point to. The reason I say pointers are typeless is because their actual type is platform specific. But for now just pretend they are typeless integers that point to a type and when you are casting what you are really casting is the type it points to.

    ^_^

    -LC
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >My compiler automatically does the cast but it is better to show the cast. I forgot exactly why.

    FAQ > Explanations of... > Casting malloc
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Comment your source code! Lynux-Penguin's Avatar
    Join Date
    Apr 2002
    Posts
    533
    damn, today 3 times I've been proven wrong. (incorrect english on purpose)

    I need some sleep. Anyone know where I can download some?

    -LC
    Asking the right question is sometimes more important than knowing the answer.
    Please read the FAQ
    C Reference Card (A MUST!)
    Pointers and Memory
    The Essentials
    CString lib

  12. #12
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Technically, all pointers are the same. A 4 byte (in most processor architectures) value pointing to a virtual adress. The cpu doesn't know whether it's a char, int, double or void pointer. These are just concepts constructed to make high-level programming more logical.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  13. #13
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Originally posted by Magos
    Technically, all pointers are the same. A 4 byte (in most processor architectures) value pointing to a virtual adress. The cpu doesn't know whether it's a char, int, double or void pointer. These are just concepts constructed to make high-level programming more logical.
    Not quite:
    ISO/IEC 9899:1999 (E)
    6.2.5 Types

    26 A pointer to void shall have the same representation and alignment requirements as a
    pointer to a character type.(39) Similarly, pointers to qualified or unqualified versions of
    compatible types shall have the same representation and alignment requirements. All
    pointers to structure types shall have the same representation and alignment requirements
    as each other. All pointers to union types shall have the same representation and
    alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

    39) The same representation and alignment requirements are meant to imply interchangeability as
    arguments to functions, return values from functions, and members of unions.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  14. #14
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    I meant on the low level. In the processor, there are no chars, voids, ints, doubles, structures, unions etc...
    What that quote meant (if I'm not mistaken) is that pointers to datatypes of the same size should be the same (as i said). Clearly, a pointer to a 2-byte datatype doesn't function exactly like a pointer to a 1-byte datatype, since you adress one of the 2 bytes and the other 'automatically follows'.
    Bah, silly explanation. I'm tired...
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using pointers to pointers
    By steve1_rm in forum C Programming
    Replies: 18
    Last Post: 05-29-2008, 05:59 AM
  2. function pointers
    By benhaldor in forum C Programming
    Replies: 4
    Last Post: 08-19-2007, 10:56 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM