handling uninitialized pointed (How to check ?? )

Discussion in 'C Programming' started by sanjaymeher@gmail.com, Dec 28, 2005.

  1. Guest

    Hi,

    Right now addDynamicMemory(char **ptr, int size) method can able to
    handle if input ptr is intitialized to NULL or something. But how to
    improve this method to handle uninitialized pointed even. Any Answer ??

    Thanks,
    Sanjay


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    int addDynamicMemory(char **ptr, int size)
    {
    /* See and chek whether size memory is available or not */
    int currSize;
    if(*ptr == NULL)
    {
    *ptr = (char*) malloc(size * sizeof(char));
    if(ptr == NULL)
    {
    printf("Initialized memory as null \n");
    return -1;
    }
    else
    {
    printf("Can not Initialized memory as null \n");
    return -1;
    }
    }

    currSize = strlen(*ptr);
    size = currSize + size;
    *ptr = (char*) realloc(*ptr, size*sizeof(char));

    if(ptr != NULL)
    {
    printf(" re Allocation size is %d\n",size);
    return 0;
    }

    printf(" re Allocation failed \n");
    return -1;
    }

    //int main(int argc, char* argv[])
    void main()
    {
    char *test;
    test = NULL;

    addDynamicMemory(&test, 40);
    printf("At first test value is %s\n",test);
    strcpy(test,"444444444");
    printf("After allocation val is %s\n", test);

    addDynamicMemory(&test, 50);
    strcat(test,"5555555555");
    printf("After allocation val is %s\n", test);
    }
     
    , Dec 28, 2005
    #1
    1. Advertising

  2. said:

    > Hi,
    >
    > Right now addDynamicMemory(char **ptr, int size) method can able to
    > handle if input ptr is intitialized to NULL or something. But how to
    > improve this method to handle uninitialized pointed even. Any Answer ??


    Don't send it uninitialised pointers.

    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    >
    > int addDynamicMemory(char **ptr, int size)


    int addDynamicMemory(char **ptr, size_t size)

    > {
    > /* See and chek whether size memory is available or not */
    > int currSize;


    size_t currSize;
    char *tmp; /* you'll need this in a minute */

    > if(*ptr == NULL)


    If ptr is NULL, *ptr is a bad move.

    > {
    > *ptr = (char*) malloc(size * sizeof(char));


    *ptr = malloc(size);

    > if(ptr == NULL)


    Too late.

    > {
    > printf("Initialized memory as null \n");
    > return -1;
    > }
    > else
    > {
    > printf("Can not Initialized memory as null \n");
    > return -1;
    > }
    > }
    >
    > currSize = strlen(*ptr);
    > size = currSize + size;
    > *ptr = (char*) realloc(*ptr, size*sizeof(char));


    currSize = strlen(*ptr);
    tmp = realloc(*ptr, size);
    if(tmp != NULL)
    {
    *ptr = tmp;
    size += currSize;
    }
    else
    {
    You have some work to do. The call failed. How will you handle this?
    }

    >
    > if(ptr != NULL)
    > {
    > printf(" re Allocation size is %d\n",size);


    Because the right type for size is size_t, %d won't cut it any more.

    > return 0;
    > }
    >
    > printf(" re Allocation failed \n");
    > return -1;
    > }
    >
    > //int main(int argc, char* argv[])
    > void main()


    int main(void)

    > {
    > char *test;
    > test = NULL;


    char *test = NULL;

    > addDynamicMemory(&test, 40);


    Why bother returning a value if you don't test it?

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Dec 28, 2005
    #2
    1. Advertising

  3. Madhav Guest

    wrote:

    > Hi,
    >
    > Right now addDynamicMemory(char **ptr, int size) method can able to
    > handle if input ptr is intitialized to NULL or something. But how to
    > improve this method to handle uninitialized pointed even. Any Answer ??
    >

    Do you mean to check for pointers containing random values other than
    NULL? I think you are talking about a case when you just pass a pointer
    to your addDynamicMemory( ) which is not "malloc()ed" and which is not
    null.

    I think you cannot test this case. Either you have to make it NULL
    explicitly before passing it to your own addDynamicMemory() or allocate
    some space for it.

    Please correct me if I am wrong.

    -Madhav.
     
    Madhav, Dec 28, 2005
    #3
  4. Guest

    I just want to call like this


    void main()
    {
    char *test;
    //test = NULL; (Dont want to initialize it here ......)

    addDynamicMemory(&test, 40);

    }
     
    , Dec 28, 2005
    #4
  5. said:

    > I just want to call like this
    >
    >
    > void main()


    main returns int. I told you that already, I'm sure. If you can't get that
    right, you are not ready for malloc.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Dec 28, 2005
    #5
  6. Guest

    wrote:
    > I just want to call like this
    >
    > void main()


    int main()

    > {
    > char *test;
    > //test = NULL; (Dont want to initialize it here ......)
    >


    Simple:

    char *test = NULL;

    If you ALWAYS declare pointers like this, you will have no problems.
    The answer is simply to NEVER declare pointer without initialising it
    to NULL. If you see anywhere in your code where you declare a pointer
    that is not initialised to NULL consider is a BUG. It's only 8
    characters including spacebars, why not just type it?

    Again: ALWAYS declare pointers by initialising it to NULL:

    char *test = NULL;
    int *idx = NULL;
    char *buffer = NULL;
    ...
     
    , Dec 28, 2005
    #6
  7. Madhav Guest

    wrote:

    > I just want to call like this
    >
    >
    > void main()
    > {
    > char *test;
    > //test = NULL; (Dont want to initialize it here ......)
    >
    > addDynamicMemory(&test, 40);
    >
    > }


    The problem in this case is that you dont know (and can't check)
    whether the "test" pointer points to a valid address in the heap. In
    the code above, it could point to anything because the standard does
    not specify initial value for pointers.

    Also, please change the return type of main to int, and add a
    "void" within the brackets if you don't want to use the command line
    arguments.
     
    Madhav, Dec 28, 2005
    #7
  8. wrote:
    > I just want to call like this
    >
    >
    > void main()

    ^^^^
    No, you don't. You're dead already.
     
    Martin Ambuhl, Dec 28, 2005
    #8
  9. In article <>,
    <> wrote:
    >Hi,
    >
    > Right now addDynamicMemory(char **ptr, int size) method can able to
    >handle if input ptr is intitialized to NULL or something. But how to
    >improve this method to handle uninitialized pointed even. Any Answer ??


    I don't know. Speak English, maybe?
     
    Kenny McCormack, Dec 28, 2005
    #9
  10. Guest

    I wanted this method to be full proof to be used by other user. My
    method should able to handle if any uninitialized variable is coming..
    This is really not the good part of C language if i try to speak
    ENGLISH ....

    Thanks
    Sanjay
     
    , Dec 28, 2005
    #10
  11. said:

    > I wanted this method to be full proof to be used by other user. My
    > method should able to handle if any uninitialized variable is coming..


    You simply can't do it, at least not without writing your own implementation
    and then requiring all your users to use it. This solution might just be
    considered beyond the scope of the discussion.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Dec 28, 2005
    #11
  12. pemo Guest

    "Richard Heathfield" <> wrote in message
    news:dou40t$pcd$-infra.bt.com...
    > said:
    >
    >> I wanted this method to be full proof to be used by other user. My
    >> method should able to handle if any uninitialized variable is coming..

    >
    > You simply can't do it, at least not without writing your own
    > implementation
    > and then requiring all your users to use it. This solution might just be
    > considered beyond the scope of the discussion.


    As you've been told, you can't do this in C.

    You perhaps ought to look at C++ - where one can use a smart-pointer that
    'knows' whether it's been assigned to and/or explicitly initialised.

    A rather old book that goes into this kind of thing at length is called 'C++
    Pointers and Dynamic Memory Management' [yes, it's a whole book on these
    prickly subjects]. Probably out of print now; though you can find plenty of
    web sources on this subject.
     
    pemo, Dec 28, 2005
    #12
  13. Chad Guest

    Richard Heathfield wrote:
    > said:
    >
    > > Hi,
    > >
    > > Right now addDynamicMemory(char **ptr, int size) method can able to
    > > handle if input ptr is intitialized to NULL or something. But how to
    > > improve this method to handle uninitialized pointed even. Any Answer ??

    >
    > Don't send it uninitialised pointers.
    >
    > > #include <stdio.h>
    > > #include <stdlib.h>
    > > #include <string.h>
    > >
    > > int addDynamicMemory(char **ptr, int size)

    >
    > int addDynamicMemory(char **ptr, size_t size)
    >
    > > {
    > > /* See and chek whether size memory is available or not */
    > > int currSize;

    >
    > size_t currSize;
    > char *tmp; /* you'll need this in a minute */
    >
    > > if(*ptr == NULL)

    >
    > If ptr is NULL, *ptr is a bad move.
    >


    Maybe I didn't think about this enough, but how can *ptr be a bad move.
    When i go something like:

    #include <stdlib.h>
    #include <string.h>

    int addmem(char **ptr, size_t size) {

    if(*ptr == NULL) {
    printf("Nada \n");
    exit(1);
    }
    return 0;
    }

    int main(void) {
    char *test = NULL;
    addmem(&test, 40);

    return 0;
    }

    I get the following:
    > gcc -Wall dyn.c -o dyn
    > ./dyn

    Nada
    >


    However, when I change the expression to
    if(ptr == NULL)
    my computer outputs nothing.

    Chad
     
    Chad, Dec 28, 2005
    #13
  14. Chad Guest

    Chad wrote:
    > Richard Heathfield wrote:
    > > said:
    > >
    > > > Hi,
    > > >
    > > > Right now addDynamicMemory(char **ptr, int size) method can able to
    > > > handle if input ptr is intitialized to NULL or something. But how to
    > > > improve this method to handle uninitialized pointed even. Any Answer ??

    > >
    > > Don't send it uninitialised pointers.
    > >
    > > > #include <stdio.h>
    > > > #include <stdlib.h>
    > > > #include <string.h>
    > > >
    > > > int addDynamicMemory(char **ptr, int size)

    > >
    > > int addDynamicMemory(char **ptr, size_t size)
    > >
    > > > {
    > > > /* See and chek whether size memory is available or not */
    > > > int currSize;

    > >
    > > size_t currSize;
    > > char *tmp; /* you'll need this in a minute */
    > >
    > > > if(*ptr == NULL)

    > >
    > > If ptr is NULL, *ptr is a bad move.
    > >

    >
    > Maybe I didn't think about this enough, but how can *ptr be a bad move.
    > When i go something like:
    >
    > #include <stdlib.h>
    > #include <string.h>
    >
    > int addmem(char **ptr, size_t size) {
    >
    > if(*ptr == NULL) {
    > printf("Nada \n");
    > exit(1);
    > }
    > return 0;
    > }
    >
    > int main(void) {
    > char *test = NULL;
    > addmem(&test, 40);
    >
    > return 0;
    > }
    >
    > I get the following:
    > > gcc -Wall dyn.c -o dyn
    > > ./dyn

    > Nada
    > >

    >
    > However, when I change the expression to
    > if(ptr == NULL)
    > my computer outputs nothing.
    >
    > Chad


    I just noticed that I cut and pasted the sample code, I forgot to
    include
    #include<stdio.h>
     
    Chad, Dec 28, 2005
    #14
  15. Anand Guest

    Chad wrote:
    > Richard Heathfield wrote:

    [...]
    >>>int addDynamicMemory(char **ptr, int size)

    [...]
    >>>if(*ptr == NULL)

    >>
    >>If ptr is NULL, *ptr is a bad move.
    >>

    >
    >
    > Maybe I didn't think about this enough, but how can *ptr be a bad move.
    > When i go something like:
    >
    > #include <stdlib.h>
    > #include <string.h>
    >
    > int addmem(char **ptr, size_t size) {
    >
    > if(*ptr == NULL) {
    > printf("Nada \n");
    > exit(1);
    > }
    > return 0;
    > }
    >
    > int main(void) {
    > char *test = NULL;
    > addmem(&test, 40);
    >
    > return 0;
    > }
    >
    > I get the following:
    >
    >>gcc -Wall dyn.c -o dyn
    >>./dyn

    >
    > Nada
    >
    >
    > However, when I change the expression to
    > if(ptr == NULL)
    > my computer outputs nothing.
    >
    > Chad
    >

    There are two levels of check that is required here.

    What happens if I call: addmem(NULL, 40);

    So, it's upto you to decide what level of protection you are giving
    about bad/wrong usage of your code.

    I think, what Richard Heathfield was suggesting was to provide this one
    extra level of blanket to ensure that ptr itself to be non-NULL before
    redirecting it.

    In general, IMHO, it's always a good idea to ensure the ptr is non-NULL
    before its redirection (at least its first redirection in your
    module/function.)

    So an assert( ptr != NULL );
    or
    if (ptr != NULL)
    {
    printf("WTH?\n");// or WTF if you prefer
    ....
    }
    and then followed by the *ptr != NULL test is bit more idiot-proof.
    --
    (Welcome) http://www.ungerhu.com/jxh/clc.welcome.txt
    (clc FAQ) http://c-faq.com
     
    Anand, Dec 28, 2005
    #15
  16. Anand Guest

    Anand wrote:
    [...]

    > So an assert( ptr != NULL );
    > or
    > if (ptr != NULL)

    [...]
    Oops. I mean if (ptr == NULL) here.
    Another case of Cut and Paste typo.
     
    Anand, Dec 28, 2005
    #16
  17. Chris Torek Guest

    In article <>
    <> wrote:
    >I wanted this
    Code:
     to be [fool]proof ... [and thus catch[/color]
     uninitialized variables]
    
    There is really nothing special about pointers in this regard.
    Consider a simple function int f(int x) that returns (x + 1) mod 5,
    i.e., counts 0, 1, 2, 3, 4, 0, 1, ....  We can write this as:
    
        int f(int x) {
            ++x;
            if (x >= 5)
                x -= 5;
            return x;
        }
    
    But if you call f() with an uninitialized variable, you may get
    an out-of-range result: f(1234) produces 1230, and f(-7) produces
    -6.  So:
    
        void g(void) {
            int i;    /* note lack of initializer */
    
            i = f(i); /* ERROR, UNPREDICTABLE */
            ...
        }
    
    Suppose you attempt to catch this with:
    
        int f(int x) {
            if (x < 0 || x > 4)
                panic("f: x = %d: out of range", x);
            ++x;
            if (x >= 5)
                x -= 5;
            return x;
        }
    
    This will in fact catch many "bad" calls to f() -- but in g(), if
    the uninitialized i "just happens" to be 2, it will look, to f()
    at least, like a perfectly valid value.
    
    The same holds for pointers:
    
        void h(void) {
            char *p;   /* note lack of initializer */
    
            p = f2(p); /* ERROR, UNPREDICTABLE */
            ...
        }
    
    Inside f2(), the pointer argument may well "look invalid" under
    some (machine-dependent) inspection technique -- just as an out of
    range value of x in f() can be discovered -- but it might also
    "look valid", just as x might be equal to 2 despite being uninitialized.
    
    Now, a good compiler may produce a warning for the call to f() in
    g(), or the call to f2() in h, because the compiler can tell that
    the variables in question (i and p respectively) have never been
    assigned a value before their value is used.  No diagnostic is
    *required*, but a good compiler should be able to provide one,
    because the error is quite obvious even to a simple mechanical
    analysis.
    
    Unfortunately, if we start passing the addresses of the variables
    (instead of their values), this simple analysis breaks down.  Here
    is a revised f() and g(), for instance:
    
        void f2(int *xp) {
            int x = *xp;
    
            if (x < 0 || x > 4)
                panic("f: x = %d: out of range", x);
            ++x;
            if (x >= 5)
                x -= 5;
            *xp = x;
        }
    
        void g2(void) {
            int i;  /* note lack of initializer */
    
            f2(&i); /* ERROR, UNPREDICTABLE */
            ...
        }
    
    Here the compiler can no longer use the trivial, local-only,
    mechanical analysis technique to discover that the un-initialized,
    non-existent value in "i" is being passed.  f2() gets a pointer to
    i, so it is able to change i, so there are versions of f2() that
    would make the call from g2() legal.  For instance, if we rewrite
    f2() as:
    
        void f2(int *xp) { *xp = 42; }
    
    the call in g2() is now "legal" or "correct".
    
    There are languages (see Ada) in which one annotates one's function
    parameters as to whether a reference ("pointer") is "in", "out",
    or "in out": whether the original value is used ("in"), and whether
    a new value is stored ("out").  If the original value is used *and*
    a new value is stored, the parameter is "in out".  If C had this,
    we might write:
    
        void f2(in out int *xp) {
            ...
        }
    
    and then a good compiler *could* use simple local mechanical analysis
    to produce a warning for g2().  But C does not have this, so if
    you want good compilers that use only simple local mechanical
    analysis to warn about uninitialized values of parameters, you must
    take the actual values as arguments, rather than a pointer to the
    variable that stores the value.
    
    Of course, nothing says that a C compiler has to do simple local
    mechanical analysis (or even be "good", for that matter).  A "very
    good" compiler that does interprocedural analysis would be able to
    discover that *xp is "in out" and warn you that the call from g2()
    is invalid.  A "bad" compiler that does no analysis at all will
    not warn you even with the "obvious" bad call to f() from g().
    -- 
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W)  +1 801 277 2603
    email: forget about it   http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Dec 28, 2005
    #17
  18. Chad said:
    > Richard Heathfield wrote:
    >>
    >> > if(*ptr == NULL)

    >>
    >> If ptr is NULL, *ptr is a bad move.
    >>

    >
    > Maybe I didn't think about this enough, but how can *ptr be a bad move.


    If ptr is NULL, you're not pointing to a valid char * object, so you can't
    dereference the pointer (to get the value of that non-existent object)
    without invoking undefined behaviour.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Dec 28, 2005
    #18
  19. "" <> writes:

    > wrote:
    > > I just want to call like this
    > >
    > > void main()

    >
    > int main()
    >
    > > {
    > > char *test;
    > > //test = NULL; (Dont want to initialize it here ......)
    > >

    >
    > Simple:
    >
    > char *test = NULL;
    >
    > If you ALWAYS declare pointers like this, you will have no problems.
    > The answer is simply to NEVER declare pointer without initialising it
    > to NULL. If you see anywhere in your code where you declare a pointer
    > that is not initialised to NULL consider is a BUG. It's only 8
    > characters including spacebars, why not just type it?


    So where is the bug in this code?

    #include <stdio.h>

    /* pointer not initialised to NULL following... */
    const char* msg = "This is a message.";

    int main(void)
    {
    printf("%s\n", msg);
    return 0;
    }

    /Niklas Norrthon
     
    Niklas Norrthon, Dec 29, 2005
    #19
  20. "" <> writes:
    [ about allowing a function to handle both initialized and
    uninitalized pointers ]
    > I wanted this method to be full proof to be used by other user. My
    > method should able to handle if any uninitialized variable is coming..


    This is a problem that should be solved by design and documentation.

    The design of your function dictates how it can be used, and the
    documentation passes this information along to the programmers that
    write code that calls the function.

    In C it is impossible to determine if a variable has been properly
    initialized by just looking at its value. This is a fact that we
    have to live with, and it applies to all types not just pointers.

    For non NULL pointers that are initialized in a proper way it is
    also impossible to determine if they point to static, automatic,
    or free store memory (globals, locals, or heap).

    This means that a function that during the design of a function
    taking pointer arguments it is necessary to determine what types
    of pointers the function can accept, and what to do if wrong
    kind of pointers are passed to the function. To see examples
    of such design decisions one does only have to take a look at
    the documentation of the standard library:

    size_t strlen(const char* ptr):
    Argument must be an initialized pointer to nul-terminated
    string. Anything else leads to undefined behavior.

    size_t strcpy(char* dest, const char* src):
    First argument must be initialized to point to allocated memory
    big enough to hold the string pointed to by the second arguemnt.
    The second argument must point to a nul-terminated string.
    Anything else leads to undefined behaviour

    void free(void* ptr):
    Argument must be NULL, or exactly the same as has previously
    been returned by malloc, calloc or realloc (and not been passed
    to free or realloc in between). Anything else is undefined
    behavior.

    It is perfectly acceptable to demand of a caller that pointer
    parameters are of specific kinds, just make sure that it is
    documented so that the programmer writing code calling the
    function knows what the function expects.

    /Niklas Norrthon
     
    Niklas Norrthon, Dec 29, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page