473,382 Members | 1,726 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Pointers to dead objects

6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."

Do I understand it right that value of pointer may
or may not change? What I am wondering about is this:

int a_func (void)
{
char *s = malloc (10);

if (s)
{
do_something (s);
free (s);
}

/* return 0 if malloc failed */
return s != NULL;
}

Standard says nobody knows what happens here if malloc
succeeded (is it undefined behavior, by the way?), but why
is it so? Clearly accessing freed memory is no good ("If an
object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?
More precisely, does someone know what's the rationale for this,
or what good can it do? (Answer to question "why" is "because
standard says so", of course)

Sure, it's easy to work this specific thing around by adding some
boolean which remembers if malloc succeeded or not, and many
probably would consider above code a poor style. I am just
curious, why standard allows compiler to alter pointer value
without explicit programmer action.

Regards,
Yevgen
Oct 6 '06 #1
31 2299


On Oct 6, 9:07 am, Yevgen Muntyan <muntyan.removet...@tamu.eduwrote:
6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."

Do I understand it right that value of pointer may
or may not change? What I am wondering about is this:
Even if its value is NOT changed, you still can't reference it, because
the storage it points to is freed.
int a_func (void)
{
char *s = malloc (10);

if (s)
{
do_something (s);
free (s);
}

/* return 0 if malloc failed */
return s != NULL;
In your example, 's' is NOT changed after free, of course. If it is
intended to be changed, you should pass the pointer to the pointer 's'.
But you didn't and can't.
}Standard says nobody knows what happens here if malloc
succeeded (is it undefined behavior, by the way?), but why
is it so? Clearly accessing freed
C99 7.20.3.3: "The malloc function returns either a null pointer or a
pointer to the allocated space." Of course, if malloc succeeded, it
will surely returned a pointer to the allocated space! How can it be an
undefined behavior? The only undefined thing is the value of the
allocated space.

memory is no good ("If an
object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?
You are free to use the pointer itself. The function free() doesn't
change its value. You CAN compare it to NULL if you like.
More precisely, does someone know what's the rationale for this,
or what good can it do? (Answer to question "why" is "because
standard says so", of course)
Do NOT reference a freed pointer.
Sure, it's easy to work this specific thing around by adding some
boolean which remembers if malloc succeeded or not, and many
probably would consider above code a poor style. I am just
curious, why standard allows compiler to alter pointer value
without explicit programmer action.

Regards,
Yevgen
Oct 6 '06 #2
Yevgen Muntyan <mu****************@tamu.eduwrites:
6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."

Do I understand it right that value of pointer may
or may not change? What I am wondering about is this:
[snip]

There's been a great deal of argument about that. Here's the
side of the argument that I found convincing.

Objects are made of bytes; those bytes are themselves objects.

After a successful call to malloc(), I can extract the bytes composing
the resulting pointer value (by, for example, memcpy()ing them to an
array of unsgined char). I then pass the value of the pointer to
free(); since free()'s argument is, like all function arguments,
passed by value, this logically cannot change the value of the pointer
object. If I then extract the bytes composing the pointer value
again, they'd better be the same as what I got before calling free().

The value (more precisely, the representation) doesn't change; it's
still the same bit pattern. What changes is that that bit pattern,
which *wasn't* indeterminate, now *is* indeterminate. The standard
isn't saying that "the value of the pointer changes new value; that
new value is indeterminate"; it's saying "the (unchanged) value of the
pointer, which was not indeterminate, becomes indeterinate".

Or I suppose you could say that the (unchange) representation
represents one value before free(), and a potentially different value
after free().

There are other interpretations. It's not 100% clear that free()
*can't* change the representation of the pointer; you certainly can't
tell by looking at the pointer value directly, since doing so invokes
undefined behavior. But this would require considerable compiler
magic. Consider, for example, that the argument to free() needn't be
an object value:

char *ptr = malloc(10);
if (ptr != NULL) {
char *ptr_plus_one = ptr + 1;
free(ptr_plus_one - 1);
}

As a programmer, all you really need to worry about is: Don't examine
the value of a pointer after it's been passed to free(), or after the
object to which it points otherwise ceases to exist. Doing so invokes
undefined behavior. If you want to examine it indirectly, by treating
it as an array of bytes, be sure you know just what you're doing.
(Though the theoretical points are interesting too, at least to me.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 6 '06 #3
When malloc succeeds, you expect s != NULL to evaluate to 1. However, after a
call to free(s), s != NULL could evaluate to 0; a return value that indicates
malloc failed when it really didn't. This is what "indeterminate" means.

-Matt

Yevgen Muntyan wrote:
6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."

Do I understand it right that value of pointer may
or may not change? What I am wondering about is this:

int a_func (void)
{
char *s = malloc (10);

if (s)
{
do_something (s);
free (s);
}

/* return 0 if malloc failed */
return s != NULL;
}

Standard says nobody knows what happens here if malloc
succeeded (is it undefined behavior, by the way?), but why
is it so? Clearly accessing freed memory is no good ("If an
object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?
More precisely, does someone know what's the rationale for this,
or what good can it do? (Answer to question "why" is "because
standard says so", of course)

Sure, it's easy to work this specific thing around by adding some
boolean which remembers if malloc succeeded or not, and many
probably would consider above code a poor style. I am just
curious, why standard allows compiler to alter pointer value
without explicit programmer action.

Regards,
Yevgen
Oct 6 '06 #4
Matt Kowalczyk <ma******@comcast.netwrites:
When malloc succeeds, you expect s != NULL to evaluate to 1.
However, after a call to free(s), s != NULL could evaluate to 0; a
return value that indicates malloc failed when it really didn't.
This is what "indeterminate" means.
Please don't top-post. See:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

You're mostly correct, but there's more to it. An indeterminate value
is "either an unspecified value or a trap representation". Attempting
to access an object that has a trap representation invokes undefined
behavior; it might appear to be equal to NULL, or unequal to NULL, or
a fish.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 6 '06 #5
Keith Thompson wrote:
Yevgen Muntyan <mu****************@tamu.eduwrites:
>>6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."

Do I understand it right that value of pointer may
or may not change? What I am wondering about is this:

[snip]

There's been a great deal of argument about that. Here's the
side of the argument that I found convincing.

Objects are made of bytes; those bytes are themselves objects.

After a successful call to malloc(), I can extract the bytes composing
the resulting pointer value (by, for example, memcpy()ing them to an
array of unsgined char). I then pass the value of the pointer to
free(); since free()'s argument is, like all function arguments,
passed by value, this logically cannot change the value of the pointer
object. If I then extract the bytes composing the pointer value
again, they'd better be the same as what I got before calling free().

The value (more precisely, the representation) doesn't change; it's
still the same bit pattern. What changes is that that bit pattern,
which *wasn't* indeterminate, now *is* indeterminate. The standard
isn't saying that "the value of the pointer changes new value; that
new value is indeterminate"; it's saying "the (unchanged) value of the
pointer, which was not indeterminate, becomes indeterinate".

Or I suppose you could say that the (unchange) representation
represents one value before free(), and a potentially different value
after free().
Sorry, I still don't understand what it means. It is clear that
the pointer is no longer a pointer to an object, so you can't e.g.
dereference it. But I can't understand what it means for a pointer
to be "determinate" or "indeterminate". Or is it exactly "whether it
points to something"? If it is, it's not quite clear why comparing
the pointer to NULL should not still work.

I thought "value ... becomes indeterminate" means "value may or may
not change". While it would be different from what you usually expect
(like, free() would change its argument which is impossible with
"normal" functions), it would be clear - "pointer is garbage as well
as memory which was pointed by it".
>
There are other interpretations. It's not 100% clear that free()
*can't* change the representation of the pointer; you certainly can't
tell by looking at the pointer value directly, since doing so invokes
undefined behavior. But this would require considerable compiler
magic. Consider, for example, that the argument to free() needn't be
an object value:

char *ptr = malloc(10);
if (ptr != NULL) {
char *ptr_plus_one = ptr + 1;
free(ptr_plus_one - 1);
}

As a programmer, all you really need to worry about is: Don't examine
the value of a pointer after it's been passed to free(), or after the
object to which it points otherwise ceases to exist.
Well, this is clear, it's what standard says (I think).
Doing so invokes
undefined behavior. If you want to examine it indirectly, by treating
it as an array of bytes, be sure you know just what you're doing.
(Though the theoretical points are interesting too, at least to me.)
It seems to be a bit different question: if a sequence of bits
represented a pointer to an object at some point, can it be equal (==)
to NULL bit pattern after referenced object dies? Or, in general,
are pointers so wild creatures that comparing them depends on
time, not just on their value (bit pattern)? (Note, it's different
from the thing that two different bit patterns may represent one
object, since here we have NULL and an object, eventhough dead).

Now if answer is yes, then it's clear that you can't compare
pointer to a dead object to NULL. But if answer is no, then
why stanard prohibits doing that?

Regards,
Yevgen
Oct 6 '06 #6
Cong Wang wrote:

[snip]
>>object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?


You are free to use the pointer itself. The function free() doesn't
change its value. You CAN compare it to NULL if you like.
Standard says it's UB: "The value of a pointer to an object whose
lifetime has ended is used" (J.2)
Though if pointers are so wild, then maybe "p == NULL" does not
constitute "using its value" :)
>
>>More precisely, does someone know what's the rationale for this,
or what good can it do? (Answer to question "why" is "because
standard says so", of course)


Do NOT reference a freed pointer.
Sure, this one is perfectly clear, you don't even need standard
for this. But the above code does work well on several popular
platforms (naturally), and it's only standard that says "don't do
that".

Best regards,
Yevgen
Oct 6 '06 #7
Keith Thompson wrote:
Matt Kowalczyk <ma******@comcast.netwrites:
>>When malloc succeeds, you expect s != NULL to evaluate to 1.
However, after a call to free(s), s != NULL could evaluate to 0; a
return value that indicates malloc failed when it really didn't.
This is what "indeterminate" means.


Please don't top-post. See:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

You're mostly correct, but there's more to it. An indeterminate value
is "either an unspecified value or a trap representation".
So, a bit pattern may be or may not be "trap representation" depending
on where and when it's accessed, like in this case, after freeing object
pointed to by the pointer, when the bit pattern didn't change?

Regards,
Yevgen
Oct 6 '06 #8
In article <%_hVg.31017$Oh3.30554@trnddc04>
Yevgen Muntyan <mu****************@tamu.eduwrote:
>6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."

Do I understand it right that value of pointer may
or may not change?
The bit pattern stored in the object (the "representation")
does not change, but the value that this bit pattern represents
could. See <http://web.torek.net/torek/c/numbers2.html>.
--
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.
Oct 6 '06 #9


On Oct 6, 10:22 am, Yevgen Muntyan <muntyan.removet...@tamu.edu>
wrote:
Cong Wang wrote:[snip]
>object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?
You are free to use the pointer itself. The function free() doesn't
change its value. You CAN compare it to NULL if you like.Standard says it's UB: "The value of a pointer to an object whose
lifetime has ended is used" (J.2)
Though if pointers are so wild, then maybe "p == NULL" does not
constitute "using its value" :)
Er, right. But as Keith Thompson said above, "The value (more
precisely, the representation) doesn't change; it's
still the same bit pattern."
And I also want to Keith Thompson explain why we can't compare it to
NULL even if its value is not changed. ;-p
>
>More precisely, does someone know what's the rationale for this,
or what good can it do? (Answer to question "why" is "because
standard says so", of course)
Do NOT reference a freed pointer.Sure, this one is perfectly clear, you don't even need standard
for this. But the above code does work well on several popular
platforms (naturally), and it's only standard that says "don't do
that".

Best regards,
Yevgen
I got a mistake. I thought 'reference' means accessing the value. In
fact, it is 'dereference'. I am not an English speaker. ;-(

Oct 6 '06 #10
Chris Torek wrote:
In article <%_hVg.31017$Oh3.30554@trnddc04>
Yevgen Muntyan <mu****************@tamu.eduwrote:
>>6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."

Do I understand it right that value of pointer may
or may not change?


The bit pattern stored in the object (the "representation")
does not change, but the value that this bit pattern represents
could. See <http://web.torek.net/torek/c/numbers2.html>.
Indeed, my "what the heck" is really "why the heck does it need
to know whether p is valid or not to compare it to NULL?". But
then one could tell "why the heck not? it may be dumb and
inspect pointed memory everytime to collect statistical data
to print a popularity chart" :)
And since accessing pointer to a dead object is really cheap to
avoid, there's probably no point to prohibit an implentation
doing what I don't like :)

Best regards,
Yevgen
Oct 6 '06 #11


On Oct 6, 10:17 am, Chris Torek <nos...@torek.netwrote:
In article <%_hVg.31017$Oh3.30554@trnddc04>
Yevgen Muntyan <muntyan.removet...@tamu.eduwrote:
6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."
Do I understand it right that value of pointer may
or may not change?The bit pattern stored in the object (the "representation")
does not change, but the value that this bit pattern represents
could. See <http://web.torek.net/torek/c/numbers2.html>.
--
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.
Why and where is the "later call to malloc()" ?

Oct 6 '06 #12
Yevgen Muntyan wrote:
Keith Thompson wrote:
>Matt Kowalczyk <ma******@comcast.netwrites:
>>When malloc succeeds, you expect s != NULL to evaluate to 1.
However, after a call to free(s), s != NULL could evaluate to 0; a
return value that indicates malloc failed when it really didn't.
This is what "indeterminate" means.

Please don't top-post. See:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

You're mostly correct, but there's more to it. An indeterminate value
is "either an unspecified value or a trap representation".


So, a bit pattern may be or may not be "trap representation" depending
on where and when it's accessed, like in this case, after freeing object
pointed to by the pointer, when the bit pattern didn't change?
Yes. One (barely) plausible scenario goes like this: imagine
a machine with "structured" pointers, where a pointer's value is
not just a number but a "page identifier" and an "offset." Imagine
further that these pointers are used by loading the "page identifer"
into a special "page pointer register," and then using the offset
separately.

With me so far? All right, now suppose that when you load a
value into a "page pointer register," this queries the MMU for a
virtual-to-physical address translation; each page pointer register
has a corresponging "physical page register," and it is the latter
that is actually used after combining with the offset. Suppose
that the MMU causes a trap if you attempt to load a "page pointer
register" with the address of a page that isn't mapped.

Finally: Suppose a free() implementation that can tell when the
very last malloc()ed area in a page is released, and suppose that
when this happens the free() implementation manipulates the MMU to
un-map the page and return it to the O/S. With all this in mind:

char *p = malloc(42);
if (p == NULL) /* PPR = page(p), PPR == 0 && off(p) == 0 */
...;
free (p); /* un-maps the page p pointed to */
if (p == NULL) /* PPR = page(p) -BAD PAGE TRAP! */

The representation of p has not changed, but the representation
lost its value when free() adjusted the MMU.

Are there any machines that actually work this way? I've seen
some posts from Committee members who mentioned some of the segmented
addressing schemes that were popular in the mid-1980s when the ANSI
Standard was being developed, and it seems that these machines were
capable of being operated in a mode something like what I've outlined
(it's not clear to me whether they actually *were* operated that way,
but the possibility apparently existed). The Committee seems to have
decided not to forbid the practice; who knows? it might actually turn
out to be useful some day. (If you don't think computer design is
fashion-driven, you haven't studied its history.) Since there is
almost nothing useful you can do with a dead pointer anyhow, the
Committee decided to prohibit doing anything at all with it; this
avoids constraining the chip designers unnecessarily.

In the end, that's what it comes down to: Specify the language
tightly enough to make it useful, but not so tightly that innovation
is stifled.

--
Eric Sosman
es*****@acm-dot-org.invalid
Oct 6 '06 #13
On Fri, 06 Oct 2006 02:22:09 GMT, Yevgen Muntyan
<mu****************@tamu.eduwrote in comp.lang.c:
Cong Wang wrote:

[snip]
>object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?

You are free to use the pointer itself. The function free() doesn't
change its value. You CAN compare it to NULL if you like.

Standard says it's UB: "The value of a pointer to an object whose
lifetime has ended is used" (J.2)
Though if pointers are so wild, then maybe "p == NULL" does not
constitute "using its value" :)

>More precisely, does someone know what's the rationale for this,
or what good can it do? (Answer to question "why" is "because
standard says so", of course)

Do NOT reference a freed pointer.

Sure, this one is perfectly clear, you don't even need standard
for this. But the above code does work well on several popular
platforms (naturally), and it's only standard that says "don't do
that".

Best regards,
Yevgen
Since you have asked this repeatedly, here is a reason why it is
undefined behavior to make any use of the value of the pointer, just
the same as it is to make any use of the value of an uninitialized
pointer, where any use includes reading the value, such as comparing
to NULL, as well as dereferencing it.

Let's look at possibilities, step-by-step:

Consider a processor with hardware memory mapping, which is not hard
to do because that is what is in all desktop and laptop computers
today.

Now let us suppose that the combination of the specific processor and
the specific compiler perform any reference to the value of a pointer,
even comparison for equality, by first loading the value of the
pointer into a processor addressing register.

And finally suppose that the processor uses the memory management
hardware to check a pointer value for validity when it is loaded into
a pointer register.

So you call malloc(), malloc() calls the system, and the system finds
available memory somewhere in the system and maps it to (for example),
0x10000000. Eventually malloc() returns that memory to your function.

You test the value for NULL, which causes the compiler to emit code to
load 0x10000000 into an address register. This causes the processor
hardware to check, and it finds that this address is valid.

Then you free() the pointer, and free() might call the system to
release the memory. It is neither required nor forbidden to do so.
The system sees that this memory block is no longer needed by the
program, so it unmaps it from the program's virtual address space.

Now you decide to test the pointer for NULL again. Again the compiler
generates code to load it into an address register. Again the
hardware checks the memory mapping table, but now it finds that the
address does not exist in the program's memory.

The processor generates a trap to the OS, which might need to check to
see if the program is trying to access swapped out memory that
actually belongs to it.

But the OS finds that the program really does not own any memory at
that logical address, so it terminates the program.

I have never used a hardware architecture that would do such checking
on loading the value of a pointer, instead of waiting until the
pointer value is dereferenced. I do not know if there are, or have
ever been, any such hardware architectures. But the C standard allows
for them, by telling you specifically that you produce undefined
behavior by making any use of the pointer value, even to compare it to
NULL.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Oct 6 '06 #14


On Oct 6, 10:54 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
Yevgen Muntyan wrote:
Keith Thompson wrote:
Matt Kowalczyk <matt5...@comcast.netwrites:
>When malloc succeeds, you expect s != NULL to evaluate to 1.
However, after a call to free(s), s != NULL could evaluate to 0; a
return value that indicates malloc failed when it really didn't.
This is what "indeterminate" means.
Please don't top-post. See:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php
You're mostly correct, but there's more to it. An indeterminate value
is "either an unspecified value or a trap representation".
So, a bit pattern may be or may not be "trap representation" depending
on where and when it's accessed, like in this case, after freeing object
pointed to by the pointer, when the bit pattern didn't change? Yes. One (barely) plausible scenario goes like this: imagine
a machine with "structured" pointers, where a pointer's value is
not just a number but a "page identifier" and an "offset." Imagine
further that these pointers are used by loading the "page identifer"
into a special "page pointer register," and then using the offset
separately.

With me so far? All right, now suppose that when you load a
value into a "page pointer register," this queries the MMU for a
virtual-to-physical address translation; each page pointer register
has a corresponging "physical page register," and it is the latter
that is actually used after combining with the offset. Suppose
that the MMU causes a trap if you attempt to load a "page pointer
register" with the address of a page that isn't mapped.

Finally: Suppose a free() implementation that can tell when the
very last malloc()ed area in a page is released, and suppose that
when this happens the free() implementation manipulates the MMU to
un-map the page and return it to the O/S. With all this in mind:

char *p = malloc(42);
if (p == NULL) /* PPR = page(p), PPR == 0 && off(p) == 0 */
...;
free (p); /* un-maps the page p pointed to */
if (p == NULL) /* PPR = page(p) -BAD PAGE TRAP! */

The representation of p has not changed, but the representation
lost its value when free() adjusted the MMU.

Are there any machines that actually work this way? I've seen
some posts from Committee members who mentioned some of the segmented
addressing schemes that were popular in the mid-1980s when the ANSI
Standard was being developed, and it seems that these machines were
capable of being operated in a mode something like what I've outlined
(it's not clear to me whether they actually *were* operated that way,
but the possibility apparently existed). The Committee seems to have
decided not to forbid the practice; who knows? it might actually turn
out to be useful some day. (If you don't think computer design is
fashion-driven, you haven't studied its history.) Since there is
almost nothing useful you can do with a dead pointer anyhow, the
Committee decided to prohibit doing anything at all with it; this
avoids constraining the chip designers unnecessarily.

In the end, that's what it comes down to: Specify the language
tightly enough to make it useful, but not so tightly that innovation
is stifled.

--
Eric Sosman
esos...@acm-dot-org.invalid
Excellent explanation! It is determined by the page trap handler of OS,
so the std says it's indeterminate. Right?

Oct 6 '06 #15
Yevgen Muntyan said:
6.2.4 of standard says:
"The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime."
Right.
Do I understand it right that value of pointer may
or may not change?
It's bound to change when it becomes indeterminate, insofar as
"indeterminate pointer" doesn't have as much value to you as "determinate
pointer", right? :-)
What I am wondering about is this:

int a_func (void)
{
char *s = malloc (10);

if (s)
{
do_something (s);
free (s);
At this point, s becomes indeterminate.
}

/* return 0 if malloc failed */
return s != NULL;
Undefined behaviour - comparison constitutes usage, and using an
indeterminate value of any kind constitutes undefined behaviour.
}

Standard says nobody knows what happens here if malloc
succeeded (is it undefined behavior, by the way?),
Yes.

* Undefined behavior --- behavior, upon use of a nonportable or
erroneous program construct, of erroneous data, or of
indeterminately-valued objects, for which the Standard imposes no
requirements.
but why is it so?
You arrive at the theatre. You purchase a ticket. It has value - it lets you
into the theatre to watch the show, and reserves a seat for you. You enjoy
the show. In due course, you head for the exit, ticket all but forgotten,
but nevertheless tucked into your wallet.

You pass through the exit, and immediately your ticket is no longer valid.
It is the same physical piece of paper, but it no longer entitles you to
*anything*. You can't use it to justify re-entering the theatre. You can't
use it to get back to your seat. And you certainly can't use it to find out
whether your seat is the one in the corner with the missing backrest.

It's similar with a pointer, after you've freed the space to which it
points. Yes, you've still got a number printed on your pointer, but no, you
no longer have a seat - and you *no longer have the right to look at the
number*. The only thing you have a right to do is cross out that number and
write a new one there.
Clearly accessing freed memory is no good ("If an
object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?
Nothing to stop an implementation only returning (from *alloc) pointers in a
given range, in which all such pointers are *either* present in a lookup
table maintained internally *or* trap representations - i.e. if they're not
kosher, they trap. That would be perfectly legal. And that's why.
Sure, it's easy to work this specific thing around by adding some
boolean which remembers if malloc succeeded or not, and many
probably would consider above code a poor style. I am just
curious, why standard allows compiler to alter pointer value
without explicit programmer action.
Sometimes there's more to value than mere numbers. Think "context".

--
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)
Oct 6 '06 #16
Richard Heathfield wrote:
Yevgen Muntyan said:
[snip]
>>but why is it so?


You arrive at the theatre. You purchase a ticket. It has value - it lets you
into the theatre to watch the show, and reserves a seat for you. You enjoy
the show. In due course, you head for the exit, ticket all but forgotten,
but nevertheless tucked into your wallet.

You pass through the exit, and immediately your ticket is no longer valid.
It is the same physical piece of paper, but it no longer entitles you to
*anything*. You can't use it to justify re-entering the theatre. You can't
use it to get back to your seat. And you certainly can't use it to find out
whether your seat is the one in the corner with the missing backrest.
I certainly can do it - I can get a chart of seats for that; and I
certainly can tell whether my seat was number 10 in row M by just
looking at the ticket, I still can look at it and read what's written
on it, it's not forbidden by theater rules.
But, as pointed out elsewhere, there may be strange theaters where
seat number is not written on the ticket and I really need to enter
theater at the time specified on the ticket to find out where the seat is :)

Regards,
Yevgen
Oct 6 '06 #17
Yevgen Muntyan said:
Richard Heathfield wrote:
>Yevgen Muntyan said:
[snip]
>>>but why is it so?


You arrive at the theatre. You purchase a ticket. It has value - it lets
you into the theatre to watch the show, and reserves a seat for you. You
enjoy the show. In due course, you head for the exit, ticket all but
forgotten, but nevertheless tucked into your wallet.

You pass through the exit, and immediately your ticket is no longer
valid. It is the same physical piece of paper, but it no longer entitles
you to *anything*. You can't use it to justify re-entering the theatre.
You can't use it to get back to your seat. And you certainly can't use it
to find out whether your seat is the one in the corner with the missing
backrest.

I certainly can do it - I can get a chart of seats for that;
No, to do that, you'd have to be the memory manager (or theatre manager, if
you prefer).
and I
certainly can tell whether my seat was number 10 in row M by just
looking at the ticket, I still can look at it and read what's written
on it, it's not forbidden by theater rules.
This theatre is in Soviet Russia, and the KGB want to know why you are
studying an out-of-date ticket. :-)

--
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)
Oct 6 '06 #18
Do you mean, if malloc failed, the return value maybe not NULL?

Keith Thompson wrote:
Matt Kowalczyk <ma******@comcast.netwrites:
When malloc succeeds, you expect s != NULL to evaluate to 1.
However, after a call to free(s), s != NULL could evaluate to 0; a
return value that indicates malloc failed when it really didn't.
This is what "indeterminate" means.

Please don't top-post. See:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

You're mostly correct, but there's more to it. An indeterminate value
is "either an unspecified value or a trap representation". Attempting
to access an object that has a trap representation invokes undefined
behavior; it might appear to be equal to NULL, or unequal to NULL, or
a fish.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 6 '06 #19
st************@gmail.com said:
Do you mean, if malloc failed, the return value maybe not NULL?
No, he doesn't mean that. I know he doesn't mean that because the Standard
guarantees that the return value of malloc is NULL on failure.

--
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)
Oct 6 '06 #20
So, Mr Heathfield, which answer do you prefer, I'm not sure of any one
above, but I think Mr Thompson's answer maybe right, if some operating
system didn't define NULL as 0.

Oct 6 '06 #21
st************@gmail.com said:
So, Mr Heathfield, which answer do you prefer,
This one.

You might want to try providing some context in future questions, so that
people have some clue about what you're actually asking.

--
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)
Oct 6 '06 #22
Yevgen Muntyan <mu****************@tamu.eduwrites:
[...]
Sorry, I still don't understand what it means. It is clear that
the pointer is no longer a pointer to an object, so you can't e.g.
dereference it. But I can't understand what it means for a pointer
to be "determinate" or "indeterminate". Or is it exactly "whether it
points to something"? If it is, it's not quite clear why comparing
the pointer to NULL should not still work.
"Indeterminate value" is a technical term, defined in the standard.
An indeterminate value is "either an unspecified value or a trap
representation". A unspecified value is a "valid value of the
relevant type where this International Standard imposes no
requirements on which value is chosen in any instance". A trap
representation is an object representation that "need not represent a
value of the object type".

Bottom line: once the pointed-to object reaches the end of its
lifetime, any attempt to look at the value of the pointer invokes
undefined behavior.
I thought "value ... becomes indeterminate" means "value may or may
not change". While it would be different from what you usually expect
(like, free() would change its argument which is impossible with
"normal" functions), it would be clear - "pointer is garbage as well
as memory which was pointed by it".
Whether the value changes or not is a subtle question, but the answer
isn't all that useful, since you can't look at the value.

[...]
It seems to be a bit different question: if a sequence of bits
represented a pointer to an object at some point, can it be equal (==)
to NULL bit pattern after referenced object dies? Or, in general,
are pointers so wild creatures that comparing them depends on
time, not just on their value (bit pattern)? (Note, it's different
from the thing that two different bit patterns may represent one
object, since here we have NULL and an object, eventhough dead).
Even for valid pointer values, the "==" operator doesn't *necessarily*
do the equivalent of bit-by-bit comparison (though it commonly does).
You could have two different representations that represent the same
pointer value; "==" still has to yield 1.

But if ptr has been passed to free(), and therefore has an
indeterminate value, evaluating ptr (in the context of "ptr == NULL")
invokes undefined behavior. Anything can happen. It can yield 0, or
1, or 42, or a bathtub filled with brightly colored machine tools.

Realistically, looking at the value of ptr probably *won't* cause a
trap, and comparing it to NULL will probably indicate that it's
unequal. But there are real-world systems where loading certain
invalid pointer values into a register can cause a trap, and the
standard certainly allows it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 6 '06 #23
"Cong Wang" <xi************@gmail.comwrites:
On Oct 6, 10:22 am, Yevgen Muntyan <muntyan.removet...@tamu.edu>
wrote:
>Cong Wang wrote:[snip]
>>object is referred to outside of its lifetime, the behavior is
undefined."), but why can't you use the pointer itself,
specifically to compare it to NULL?
You are free to use the pointer itself. The function free() doesn't
change its value. You CAN compare it to NULL if you like.
Standard says it's UB: "The value of a pointer to an object whose
lifetime has ended is used" (J.2)
Though if pointers are so wild, then maybe "p == NULL" does not
constitute "using its value" :)

Er, right. But as Keith Thompson said above, "The value (more
precisely, the representation) doesn't change; it's
still the same bit pattern."
And I also want to Keith Thompson explain why we can't compare it to
NULL even if its value is not changed. ;-p
Because just examining the value of the pointer, once that value has
become indeterminate, invokes undefined behavior.

[...]
I got a mistake. I thought 'reference' means accessing the value. In
fact, it is 'dereference'. I am not an English speaker. ;-(
"Referencing" means looking at the value of the pointer itself (e.g.,
to compare it to null). "Dereferencing" means looking at the object
that the pointer points to. Both are forbidden (i.e., invoke
undefined behavior) if the pointer itself has an indeterminate value.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 6 '06 #24
"st************@gmail.com" <st************@gmail.comwrites:
So, Mr Heathfield, which answer do you prefer, I'm not sure of any one
above, but I think Mr Thompson's answer maybe right, if some operating
system didn't define NULL as 0.
Can you rephrase the question? You seem to think that Richard and I
disagree; as far as I can tell, we don't.

malloc() returns a null pointer if it fails. If it succeeds, it
returns a non-null pointer value. If you pass that non-null pointer
value to free(), its value becomes indeterminate. (You can legally
pass a null pointer to free(); doing so does not create an
indeterminate value.)

Note that NULL is a macro that expands to an implementation-defined
null pointer constant, and 0 is a null pointer constant. This is true
regardless of whether a null pointer value is represented as
all-bits-zero or not.

Read sections 4 and 5 of the comp.lang.c FAQ. If you still have any
question, please feel free to ask.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 6 '06 #25
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>"Indeterminate value" is a technical term, defined in the standard.
An indeterminate value is "either an unspecified value or a trap
representation".
Presumably the only realistic scenario for failure here is that the
value will not change when free() is called but that the value, which
was not previously a trap representation, becomes one. If the value
was 0x12345678, it remains 0x12345678, but 0x12345678 becomes a trap
representation.

-- Richard
Oct 6 '06 #26
Richard Tobin wrote:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
"Indeterminate value" is a technical term, defined in the standard.
An indeterminate value is "either an unspecified value or a trap
representation".

Presumably the only realistic scenario for failure here is that the
value will not change when free() is called but that the value, which
was not previously a trap representation, becomes one. If the value
was 0x12345678, it remains 0x12345678, but 0x12345678 becomes a trap
representation.
I think you're confusing value and representation. (Either that, or I
am.) In your scenario, 0x12345678 is the representation, and that does
not change. The value does change: it used to point to a particular
object, and now it doesn't.

Oct 6 '06 #27
"Harald van Dijk" <tr*****@gmail.comwrites:
Richard Tobin wrote:
>In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>"Indeterminate value" is a technical term, defined in the standard.
An indeterminate value is "either an unspecified value or a trap
representation".

Presumably the only realistic scenario for failure here is that the
value will not change when free() is called but that the value, which
was not previously a trap representation, becomes one. If the value
was 0x12345678, it remains 0x12345678, but 0x12345678 becomes a trap
representation.
Yes (modulo confusion about "value" vs. "representation").
I think you're confusing value and representation. (Either that, or I
am.) In your scenario, 0x12345678 is the representation, and that does
not change. The value does change: it used to point to a particular
object, and now it doesn't.
Whether the "value" "changes", whatever we mean by either word, is a
difficult question. Consider an integer object used to hold an array
index. It currently has the value 42, and we have an array with 50
elements. Then we use realloc() to shrink the array to 25 elements.
The value is still 42, but it no longer denotes an element of the
array.

Pointers are trickier, of course; unlike integers, they have no
meaning other than designating (or not designating) some object (or
function, but I'm only talking about object pointers here).

You can say that the pointer has the same value before and after
free(), or you can say that after free() it has the same
representation, but that representation no longer represents a value
at all. I suspect the wording in the standard isn't clear enough to
resolve the question. The standard itself says that an "indeterminate
value" can be a "trap representation". Is an "indeterminate value"
always a "value"? I would think so, by ordinary English grammar, but
maybe not.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 6 '06 #28
In this, you said that "Referencing" & "Dereferencing" are fobidden, if
the pointer itself has an indeterminate value. But I do an easy
experiment on my computer.

int * ptr;
if ( ptr == NULL);

and I think maybe this is the Dereferencing what you are talking about,
when I run it on Visual Studio 2005, I got an runtime error message
told me that ptr hasn't been initialized. Compile, NO problm. And when
I use GCC - 3.x, it runs well. Is that mean GCC is not standard?

And the other question is I've said on some computer maybe the NULL is
NOT 0. You know that both the MALLOC and FREE will invoke a system
call, on different system, the system call is different, to ask for a
block of memory, can we image that if a system maybe use special system
call, and if failed it will return a value, e.g 0xFFFFFFFF, and this is
the NULL for itself. I know this is not standard, but you know there's
a lot of thing out of range of standard.

As far as I know( sorry, I can't sure here), on some system, but
serveral memory block is defined as NULL, all the pointer points to
these area will be considered NULL.

If there is some mistake, please forgive me, my english is poor!

Keith Thompson wrote:
Er, right. But as Keith Thompson said above, "The value (more
precisely, the representation) doesn't change; it's
still the same bit pattern."
And I also want to Keith Thompson explain why we can't compare it to
NULL even if its value is not changed. ;-p

Because just examining the value of the pointer, once that value has
become indeterminate, invokes undefined behavior.

[...]
I got a mistake. I thought 'reference' means accessing the value. In
fact, it is 'dereference'. I am not an English speaker. ;-(

"Referencing" means looking at the value of the pointer itself (e.g.,
to compare it to null). "Dereferencing" means looking at the object
that the pointer points to. Both are forbidden (i.e., invoke
undefined behavior) if the pointer itself has an indeterminate value.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 7 '06 #29
"st************@gmail.com" <st************@gmail.comwrites:
In this, you said that "Referencing" & "Dereferencing" are fobidden, if
the pointer itself has an indeterminate value. But I do an easy
experiment on my computer.

int * ptr;
if ( ptr == NULL);

and I think maybe this is the Dereferencing what you are talking about,
when I run it on Visual Studio 2005, I got an runtime error message
told me that ptr hasn't been initialized. Compile, NO problm. And when
I use GCC - 3.x, it runs well. Is that mean GCC is not standard?
Please don't top-post. See the following links:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

No, that doesn't mean that gcc is not standard.

You've misunderstod what "dereferencing" means. Given
int *ptr;
"dereferencing" means looking at the value of *ptr, i.e., at the int
object that ptr points to. "Referencing" arguably isn't even a word,
but it means looking at the value of ptr itself; it's probably better
to call this "accessing" or "referring to" the value of ptr.

Given your code:

int *ptr;
if (ptr == NULL); /* there's a null statement here */

the value of ptr is indeterminate because it hasn't been initialized.
On the next line, you try to refer to the value of ptr. This invokes
undefined behavior. What that really means is that you've committed
an error, but the implementation isn't required to diagnose it for
you. Anything can happen. One of the infinitely many possibilities
is that the comparison could quietly tell you that ptr is equal to
NULL. Another is that it could quietly tell you that ptr is *not*
equal to NULL. Or your program could crash, or anything else that's
physically possible could happen.
And the other question is I've said on some computer maybe the NULL is
NOT 0.
[...]

I'll repeat what I told you last night:

Read sections 4 and 5 of the comp.lang.c FAQ. If you still have any
questions, please feel free to ask.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 7 '06 #30
Keith Thompson wrote:
"Harald van Dijk" <tr*****@gmail.comwrites:
Richard Tobin wrote:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:

"Indeterminate value" is a technical term, defined in the standard.
An indeterminate value is "either an unspecified value or a trap
representation".

Presumably the only realistic scenario for failure here is that the
value will not change when free() is called but that the value, which
was not previously a trap representation, becomes one. If the value
was 0x12345678, it remains 0x12345678, but 0x12345678 becomes a trap
representation.

Yes (modulo confusion about "value" vs. "representation").
I think you're confusing value and representation. (Either that, or I
am.) In your scenario, 0x12345678 is the representation, and that does
not change. The value does change: it used to point to a particular
object, and now it doesn't.

Whether the "value" "changes", whatever we mean by either word, is a
difficult question. Consider an integer object used to hold an array
index. It currently has the value 42, and we have an array with 50
elements. Then we use realloc() to shrink the array to 25 elements.
The value is still 42, but it no longer denotes an element of the
array.

Pointers are trickier, of course; unlike integers, they have no
meaning other than designating (or not designating) some object (or
function, but I'm only talking about object pointers here).

You can say that the pointer has the same value before and after
free(), or you can say that after free() it has the same
representation, but that representation no longer represents a value
at all. I suspect the wording in the standard isn't clear enough to
resolve the question. The standard itself says that an "indeterminate
value" can be a "trap representation". Is an "indeterminate value"
always a "value"? I would think so, by ordinary English grammar, but
maybe not.
I assumed so, but having checked, it is quite clear, and trap
representations are by definition not values:
"Certain object representations need not represent a value of the
object type. [...] Such a representation is called a /trap
representation/." (6.2.6.1p5)

So my wording was wrong too, but I'm having trouble coming up with the
right wording.

"The representation of p (after free(p);) doesn't change, but the
value, if p continues to have one at all, may." ? Does that seem right?

Oct 7 '06 #31
=?utf-8?B?SGFyYWxkIHZhbiBExLNr?= wrote:
>
Keith Thompson wrote:
"Harald van Dijk" <tr*****@gmail.comwrites:
Richard Tobin wrote:
>In article <ln************@nuthaus.mib.org>,
>Keith Thompson <ks***@mib.orgwrote:
>>
>"Indeterminate value" is a technical term, defined in the standard.
>An indeterminate value is "either an unspecified value or a trap
>representation".
>>
>Presumably the only realistic scenario for failure here is that the
>value will not change when free() is called but that the value, which
>was not previously a trap representation, becomes one. If the value
>was 0x12345678, it remains 0x12345678, but 0x12345678 becomes a trap
>representation.
Yes (modulo confusion about "value" vs. "representation").
I think you're confusing value and representation. (Either that, or I
am.) In your scenario, 0x12345678 is the representation, and that does
not change. The value does change: it used to point to a particular
object, and now it doesn't.
Whether the "value" "changes", whatever we mean by either word, is a
difficult question. Consider an integer object used to hold an array
index. It currently has the value 42, and we have an array with 50
elements. Then we use realloc() to shrink the array to 25 elements.
The value is still 42, but it no longer denotes an element of the
array.

Pointers are trickier, of course; unlike integers, they have no
meaning other than designating (or not designating) some object (or
function, but I'm only talking about object pointers here).

You can say that the pointer has the same value before and after
free(), or you can say that after free() it has the same
representation, but that representation no longer represents a value
at all. I suspect the wording in the standard isn't clear enough to
resolve the question. The standard itself says that an "indeterminate
value" can be a "trap representation". Is an "indeterminate value"
always a "value"? I would think so, by ordinary English grammar, but
maybe not.

I assumed so, but having checked, it is quite clear, and trap
representations are by definition not values:
"Certain object representations need not represent a value of the
object type. [...] Such a representation is called a /trap
representation/." (6.2.6.1p5)

So my wording was wrong too, but I'm having trouble coming up with the
right wording.

"The representation of p (after free(p);) doesn't change, but the
value, if p continues to have one at all, may." ?
Does that seem right?
p doesn't continue to have one at all.
After free(p), p isn't the address of an object.
After free(p), the value of p has no meaning.

--
pete
Oct 7 '06 #32

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Akhil | last post by:
How much is Pointers different in C# compared to C++? Do we have destructors in C#? if yes, for what do we use it? -- Cheers, Akhil
39
by: Martin Jørgensen | last post by:
Hi, I'm relatively new with C-programming and even though I've read about pointers and arrays many times, it's a topic that is a little confusing to me - at least at this moment: ---- 1)...
12
by: addinall | last post by:
Hi guys and gals, Haven't been in here for a good decade or so! I'm having a braid-dead moment that is lasting for a couple of days. Declaring pointers to functions witrhin structures and...
4
by: akhilesh natani | last post by:
hi sir, sir i want to know a simple pointer concept. Q) ..... when all of thw address are integer then why we uses the pointer of type char,float etc.
64
by: Zytan | last post by:
I know there are no pointers in C#, but if you do: a = b; and a and b are both arrays, they now both point to the same memory (changing one changes the other). So, it makes them seem like...
12
by: Marcelo Fernandez | last post by:
Hi ! I was wondering if there is tool that could tell me if some of my pointers are still alive when they are suppose to be dead (in case I forget to kill them...). As you have noticed, I am...
25
by: J Caesar | last post by:
In C you can compare two pointers, p<q, as long as they come from the same array or the same malloc()ated block. Otherwise you can't. What I'd like to do is write a function int comparable(void...
2
by: StevenChiasson | last post by:
For the record, not a student, just someone attempting to learn C++. Anyway, the problem I'm having right now is the member function detAddress, of object controller. This is more or less, your...
69
by: Yee.Chuang | last post by:
When I began to learn C, My teacher told me that pointer is the most difficult part of C, it makes me afraid of it. After finishing C program class, I found that all the code I wrote in C contains...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.