Weird Pointer In C, Please Help. Code supply...

M

MQ.john

//Working Example:

#include <stdio.h>
#include <time.h>

int main ()
{
time_t rawtime; /* define rawtime as time_t */

time ( &rawtime );
printf ( "Current date and time are: %s", ctime (&rawtime) ); /*call
ctime use &rawtime*/

return 0;
}



//Not Working Example:

#include <stdio.h>
#include <time.h>

int main ()
{
time_t *rawtime; /* define rawtime as pointer point to time_t */

time ( rawtime );
printf ( "Current date and time are: %s", ctime (rawtime) ); /* call
ctime use rawtime */

return 0;
}

it's very weird in the not working example. they are all pointer.

More example here.
char t_time;
read(fd, &t_time, 25); /* working */

char *t_time;
read(fd, t_time, 25); /* Not working */

Somebody help. i get more confuse on the pointer when i write program
in C. thank you.
 
C

Chris Johnson

//Working Example:

#include <stdio.h>
#include <time.h>

int main ()
{
time_t rawtime; /* define rawtime as time_t */

Out of curiosity, why are you making this comment? This is obvious from
the code itself.
time ( &rawtime );
printf ( "Current date and time are: %s", ctime (&rawtime) ); /*call
ctime use &rawtime*/

Again, obvious comment. A better comment would quickly explain what
ctime does.
return 0;
}



//Not Working Example:

#include <stdio.h>
#include <time.h>

int main ()
{
time_t *rawtime; /* define rawtime as pointer point to time_t */

time ( rawtime );

You are sending a NULL pointer; there is no allocated memory you're
pointing to. See malloc().
printf ( "Current date and time are: %s", ctime (rawtime) ); /* call
ctime use rawtime */

return 0;
}

it's very weird in the not working example. they are all pointer.

I don't see any advantage to using a pointer and allocating over using
a straight variable. I recommend using the first example.
More example here.
char t_time;
read(fd, &t_time, 25); /* working */

char *t_time;
read(fd, t_time, 25); /* Not working */

Again, you're not allocating memory in the second example.
Somebody help. i get more confuse on the pointer when i write program
in C. thank you.

In C, you have to allocate and free memory cells by hand. See malloc()
and free().
 
W

Walter Roberson

Chris Johnson said:
(e-mail address removed) wrote:
You are sending a NULL pointer; there is no allocated memory you're
pointing to. See malloc().

You are correct about there being no allocated memory, but the
pointer being sent in could be anything, because 'auto' variables
are not automatically initialized to anything.


To emphasize to the original poster:

time_t *rawtime; only declares space to hold the pointer itself,
and does not allocate memory to hold anything pointed to.

You could, for example, say,

time_t rawtime;
time_t *rawtimeptr = &rawtime;
time( rawtimeptr );

A pointer can be used to point the beginning of an existing
object, or to point into a distinct part of an existing object
(except a bitfield), or a pointer can be used to hold the address
of memory allocated using malloc() or calloc().

A pointer can also be assigned NULL, which is promised not to point to any
object.

A pointer may also legally be set to point immediately -after- the
end of an object, provided that there is no attempt to access
memory at that location.
 
C

Christopher Benson-Manica

You are sending a NULL pointer

Nit: The pointer is uninitialized, which means that it may or may not
be a null pointer and may or may not compare equal to NULL. As
written, the code yields undefined behavior, but

time_t *rawtime = NULL;

time( rawtime );

is perfectly valid, albeit useless.
 
M

MQ.john

Chris said:
Out of curiosity, why are you making this comment? This is obvious from
the code itself.


Again, obvious comment. A better comment would quickly explain what
ctime does.


You are sending a NULL pointer; there is no allocated memory you're
pointing to. See malloc().


I don't see any advantage to using a pointer and allocating over using
a straight variable. I recommend using the first example.


Again, you're not allocating memory in the second example.


In C, you have to allocate and free memory cells by hand. See malloc()
and free().


So, when i declare the pointer, it dosen't really exist until i call
the malloc(). thanks so much Chris. i have lots of C stuff to learn :)
 
R

Richard Heathfield

(e-mail address removed) said:

So, when i declare the pointer, it dosen't really exist until i call
the malloc().

The pointer exists just fine. It simply doesn't point anywhere! The malloc
function assigns you a block of memory and returns a pointer to that
block's start address (or returns NULL to tell you it can't meet your
request). That's one way to give a pointer a useful value:

p = malloc(n * sizeof *p);

There are, of course, other ways.
 
E

Eric Sosman

[...]

So, when i declare the pointer, it dosen't really exist until i call
the malloc(). thanks so much Chris. i have lots of C stuff to learn :)

The pointer exists, but it isn't pointing to anything.
Y'know those credit card come-ons that appear in the mail,
the ones with little bits of cardboard or plastic that look
like an actual credit card? Try to buy something with one
of them, and you'll learn the difference between a card with
an actual account number and one with a bogus number -- a
pointer whose value points to something and a pointer whose
value is bogus.
 
M

MQ.john

Eric said:
[...]

So, when i declare the pointer, it dosen't really exist until i call
the malloc(). thanks so much Chris. i have lots of C stuff to learn :)

The pointer exists, but it isn't pointing to anything.
Y'know those credit card come-ons that appear in the mail,
the ones with little bits of cardboard or plastic that look
like an actual credit card? Try to buy something with one
of them, and you'll learn the difference between a card with
an actual account number and one with a bogus number -- a
pointer whose value points to something and a pointer whose
value is bogus.


Here is the first time i use the pointer and it works. in this example
i write the file use fputs library call, when i use" write" system
call, it fails. fputs and write all require " const char *str "
paramater.


/* Working,, why?? */

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

int main (int argc,char *argv[])
{
int i;
FILE *in;
time_t *c_time; /* c_time should point to anywhere.*/

for (i = 1; i < argc; i++){
in = fopen(argv,"r+");
time(c_time);
fputs(ctime(c_time), in);
fclose(in);
}
return 0;
}
 
C

Chris Dollin

//Working Example:

#include <stdio.h>
#include <time.h>

int main ()
{
time_t rawtime; /* define rawtime as time_t */

Useless comment.
time ( &rawtime );
printf ( "Current date and time are: %s", ctime (&rawtime) ); /*call
ctime use &rawtime*/

Another useless comment. Comments should say something not
obvious from the code. /Why/ something is being done is
one possibility.

(fx:snip)
int main ()
{
time_t *rawtime; /* define rawtime as pointer point to time_t */

time ( rawtime );

`rawtime` is a pointer, but it has no defined value. So using it is
a mistake. The value of an uninitialised variable is poison, unless
that variable is static (in which case it's a suitable zero).
 
C

Chris Dollin

Eric said:
[...]

So, when i declare the pointer, it dosen't really exist until i call
the malloc(). thanks so much Chris. i have lots of C stuff to learn :)

The pointer exists, but it isn't pointing to anything.
Y'know those credit card come-ons that appear in the mail,
the ones with little bits of cardboard or plastic that look
like an actual credit card? Try to buy something with one
of them, and you'll learn the difference between a card with
an actual account number and one with a bogus number -- a
pointer whose value points to something and a pointer whose
value is bogus.

Here is the first time i use the pointer and it works.

You were unlucky.
in this example
i write the file use fputs library call, when i use" write" system
call, it fails. fputs and write all require " const char *str "
paramater.

(moved section of code)
time_t *c_time; /* c_time should point to anywhere.*/

for (i = 1; i < argc; i++){
in = fopen(argv,"r+");
time(c_time);
fputs(ctime(c_time), in);
fclose(in);
}


When you do `time(c_time)`, you're implementation is free to
ignore the fact that the value of `c_time` is poison. It
treats it as a legal pointer value. Unluckily, it seems that
the value looks like a legal pointer to somewhere, so `time`
trashes that location. It could be somewhere important: part
of the malloc heap, the return address location for `main`,
the FILE* structure of `stdout` - anything.

You have now broken your program. It may look like it's
working, but that's just bad luck.

As to why it fails if you use `fwrite`, that's just /good/
luck. Probably you trashed a more sensitive location.
 
E

Eric Sosman

Eric said:
(e-mail address removed) wrote On 10/27/06 11:19,:
[...]

So, when i declare the pointer, it dosen't really exist until i call
the malloc(). thanks so much Chris. i have lots of C stuff to learn :)

The pointer exists, but it isn't pointing to anything.
Y'know those credit card come-ons that appear in the mail,
the ones with little bits of cardboard or plastic that look
like an actual credit card? Try to buy something with one
of them, and you'll learn the difference between a card with
an actual account number and one with a bogus number -- a
pointer whose value points to something and a pointer whose
value is bogus.



Here is the first time i use the pointer and it works. in this example
i write the file use fputs library call, when i use" write" system
call, it fails. fputs and write all require " const char *str "
paramater.


/* Working,, why?? */

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

int main (int argc,char *argv[])
{
int i;
FILE *in;
time_t *c_time; /* c_time should point to anywhere.*/

for (i = 1; i < argc; i++){
in = fopen(argv,"r+");
time(c_time);
fputs(ctime(c_time), in);
fclose(in);
}
return 0;
}


One of the defects of my credit card analogy is that the
card-like thing they mail you is carefully printed with an
account number that cannot be valid, and will definitely be
detected as invalid if you try to use the fake card.

The pointer variable c_time, though, contains "random
garbage," just like any other `auto' variable that has not
been initialized. By sheer luck (decide for yourself whether
it's good luck or bad), that garbage might just happen to
point at a chunk of accessible memory. The time() function
might succeed in writing to that memory, and ctime() might
then succeed in reading from it, and the program might appear
to work. Make a tiny change that "shouldn't" make a difference,
and you get slightly different random garbage, and the program
suddenly and mysteriously starts misbehaving.

Of course, you can't count on c_time pointing anywhere
in particular, and there's no telling what other variable
might occupy the memory it happens to point at. Sometimes
the garbage pointer will be altogether invalid and the code
will (probably) crash detectably; other times you'll just
scribble over something else and you may or may not suffer
from having done so.

It's as if those fake credit cards were imprinted with
completely random digits: Most such cards would probably have
invalid account numbers and get rejected if you tried to use
them, but by pure chance a few of the account numbers might
actually be valid. You might succeed in making purchases with
"random garbage" account numbers, and maybe you'd even get
away with it. But be careful! It might happen that the
account number you stumble on belongs to Bennie the Bullet.
Everybody loves Bennie -- at least, nobody he's been mad at
seems to come around any more ...
 
K

Keith Thompson

Christopher Benson-Manica said:
Nit: The pointer is uninitialized, which means that it may or may not
be a null pointer and may or may not compare equal to NULL. As
written, the code yields undefined behavior, but

time_t *rawtime = NULL;

time( rawtime );

is perfectly valid, albeit useless.

Right, and that's only because the time() function specifically does
not attempt to write the result through its pointer argument if the
argument is a null pointer. If it weren't for that special-case rule,
then the behavior of the above code would be equally undefined.

If the time() function were being defined today, there would be no
reason for it to use a pointer at all. It almost certainly would take
no arguments and return a time_t result:

time_t t = time(); /* NOT VALID C */

Its odd definition, returning a result *and* optionally storing the
same result via a pointer object, is for historical reasons (in
ancient versions of C, a long int was implemented as an array of two
16-bit ints, and you couldn't treat it as a value).

If you're trying to learn about pointers, using the time() function
isn't a bad way to do it. If you're just trying to get the current
time, there's no point in using the argument; just call time(NULL) and
use the result.
 
K

Keith Thompson

Chris Dollin said:
Useless comment.
[...]

Not at all.

In production code, yes, a comment like that would be useless, because
you expect both the author and any readers to know exactly what
"time_t rawtime;" means.

But look at it in context. The OP posted two sample programs. In one,
he had:

time_t rawtime; /* define rawtime as time_t */

In the other, he had:

time_t *rawtime; /* define rawtime as pointer point to time_t */

The comments emphasize the difference between the two alternative
declarations, which is an important point. (Incidentally, I would
have used different names.)

Furthermore, though most of us know perfectly well what the
declarations mean, the comments make it clear *to us* that the OP
knows what they mean.

A comment like this:

x = 42; /* assign 42 to x */

is useful if (and only if) the point is to explain assignment
statements.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top