By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,385 Members | 1,739 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,385 IT Pros & Developers. It's quick & easy.

handling uninitialized pointed (How to check ?? )

P: n/a
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 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
sa*********@gmail.com 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)
Dec 28 '05 #2

P: n/a
sa*********@gmail.com 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.

Dec 28 '05 #3

P: n/a
I just want to call like this
void main()
{
char *test;
//test = NULL; (Dont want to initialize it here ......)

addDynamicMemory(&test, 40);

}

Dec 28 '05 #4

P: n/a
sa*********@gmail.com 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)
Dec 28 '05 #5

P: n/a
sa*********@gmail.com 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 '05 #6

P: n/a
sa*********@gmail.com 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.

Dec 28 '05 #7

P: n/a
sa*********@gmail.com wrote:
I just want to call like this
void main()

^^^^
No, you don't. You're dead already.
Dec 28 '05 #8

P: n/a
In article <11*********************@g47g2000cwa.googlegroups. com>,
sa*********@gmail.com <sa*********@gmail.com> 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?

Dec 28 '05 #9

P: n/a
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 '05 #10

P: n/a
sa*********@gmail.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.

--
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)
Dec 28 '05 #11

P: n/a

"Richard Heathfield" <in*****@invalid.invalid> wrote in message
news:do**********@nwrdmz03.dmz.ncs.ea.ibs-infra.bt.com...
sa*********@gmail.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.

Dec 28 '05 #12

P: n/a

Richard Heathfield wrote:
sa*********@gmail.com 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

Dec 28 '05 #13

P: n/a

Chad wrote:
Richard Heathfield wrote:
sa*********@gmail.com 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>

Dec 28 '05 #14

P: n/a
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
Dec 28 '05 #15

P: n/a
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.
Dec 28 '05 #16

P: n/a
In article <11**********************@g14g2000cwa.googlegroups .com>
sa*********@gmail.com <sa*********@gmail.com> wrote:
I wanted this [code] to be [fool]proof ... [and thus catch

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 (4039.22'N, 11150.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.
Dec 28 '05 #17

P: n/a
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)
Dec 28 '05 #18

P: n/a
"sl*******@yahoo.com" <sl*******@gmail.com> writes:
sa*********@gmail.com 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
Dec 29 '05 #19

P: n/a
"sa*********@gmail.com" <sa*********@gmail.com> 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

Dec 29 '05 #20

P: n/a
Niklas Norrthon said:
"sl*******@yahoo.com" <sl*******@gmail.com> writes:
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.";


Right - it's clearly not a bug. He'd have been wiser to say something like
"anywhere where you define (not declare, define) a pointer without
initialising it to a known value (which might be NULL), consider it a bug".

--
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)
Dec 29 '05 #21

P: n/a
Niklas Norrthon wrote:
"sl*******@yahoo.com" <sl*******@gmail.com> writes:
sa*********@gmail.com 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;
}


Ah but that pointer is pointing to something. I was commenting on
pointers not pointing to anything, which IMHO should always be set to
NULL. Sanjay thought that manually setting a pointer to NULL is too
much work hence my rant about not setting it to NULL should be
considered a bug.

I went into rant mode because I was not the first person who mentioned
NULL to him but the guy insisted on not setting it to NULL. Later on
(after my rant) he said what if users of his library doesn't set the
pointer to NULL? My point is that should be considered a bug. Actually,
for Sanjay's addDynamicMemory code initialising the pointer to static
memory is indeed a bug as his function will attempt to realloc it. So
in the context of the OP's intention, not initialising a pointer to
NULL is indeed a bug.

Dec 29 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.