473,473 Members | 2,003 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Pointing past valid memory

Hello, I was wondering if the following code was ok:

// ----------- start code

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

int main(int argc, char** argv)
{
char buf[10];
memset(buf, 'a', sizeof(buf));

int i=0;
char *ptr = &buf[0];

while (1) {
if (i == sizeof(buf))
break;

char byte = *ptr++; /* *** (1) *** */
printf("%c", byte);
++i;
}
printf("\n");
return 0;
}

// ----------- end code

In the last iteration of the loop, ptr will point past the last byte
of memory allocated for this array. This is a contrived example, but
I just wanted to know whether it's ok to point past the valid memory
for this array as long as I don't read or modify the contents of
memory at that address afterwards. On the surface it seems like this
code won't cause me any problems.

Thanks,

Prashant

Jul 3 '07 #1
14 1462

<jo***********@gmail.comwrote in message
news:11**********************@d30g2000prg.googlegr oups.com...
Hello, I was wondering if the following code was ok:

// ----------- start code

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

int main(int argc, char** argv)
{
char buf[10];
memset(buf, 'a', sizeof(buf));

int i=0;
char *ptr = &buf[0];

while (1) {
if (i == sizeof(buf))
break;

char byte = *ptr++; /* *** (1) *** */
printf("%c", byte);
++i;
}
printf("\n");
return 0;
}

// ----------- end code

In the last iteration of the loop, ptr will point past the last byte
of memory allocated for this array. This is a contrived example, but
I just wanted to know whether it's ok to point past the valid memory
for this array as long as I don't read or modify the contents of
memory at that address afterwards. On the surface it seems like this
code won't cause me any problems.
Yes, that's safe. The Standard specifically allows you to set a pointer to
just past the end of an array (with the provisio that you pointed out; that
you don't actually reference that location).

--
poncho
Jul 3 '07 #2
Hi,

If your concern by saying "point past the valid memory " is ,
Would it cause a problem to point an unallocated location ? Yes it
would. Because line notated by /* *** (1) *** */ , post-increases
ptr and in the final loop ptr will show next adjacent memory
location.But we did't allocate any place for this location and we
don't know what lies in it.

But looking at your implementation , this would cause no problem
because you don't use ptr anywhere else.

On Jul 4, 12:46 am, jois.de.vi...@gmail.com wrote:
Hello, I was wondering if the following code was ok:

// ----------- start code

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

int main(int argc, char** argv)
{
char buf[10];
memset(buf, 'a', sizeof(buf));

int i=0;
char *ptr = &buf[0];
char *ptr = buf ; //this would do the same
>
while (1) {
if (i == sizeof(buf))
break;

char byte = *ptr++; /* *** (1) *** */
printf("%c", byte);
++i;
}
printf("\n");
return 0;

}

// ----------- end code

In the last iteration of the loop, ptr will point past the last byte
of memory allocated for this array. This is a contrived example, but
I just wanted to know whether it's ok to point past the valid memory
for this array as long as I don't read or modify the contents of
memory at that address afterwards. On the surface it seems like this
code won't cause me any problems.

Thanks,

Prashant

Jul 3 '07 #3
tguclu <tu**********@gmail.comwrites:
If your concern by saying "point past the valid memory " is ,
Would it cause a problem to point an unallocated location ? Yes it
would. Because line notated by /* *** (1) *** */ , post-increases
ptr and in the final loop ptr will show next adjacent memory
location.But we did't allocate any place for this location and we
don't know what lies in it.

But looking at your implementation , this would cause no problem
because you don't use ptr anywhere else.
[...]

Please don't top-post. Read the following for more information:

http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

I think you've misunderstood the rules about pointers.

Creating a pointer value that points just past the end of an array is
legal. (The standard explicitly allows this as a special case,
because it's useful for some algorithms.) Attempting to dereference
such a pointer invokes undefined behavior.

Creating a pointer value that points *beyond* the end of an array, or
before its beginning, invokes undefined behavior. Just creating such
a pointer value invokes UB, even if you don't dereference 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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 3 '07 #4
jo***********@gmail.com wrote:
while (1) {
if (i == sizeof(buf))
break;
The non bizarre way of writing that, is:

while (i != sizeof(buf)) {

--
pete
Jul 4 '07 #5

<jo***********@gmail.comha scritto nel messaggio news:11**********************@d30g2000prg.googlegr oups.com...
Hello, I was wondering if the following code was ok:

// ----------- start code

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

int main(int argc, char** argv)
{
char buf[10];
memset(buf, 'a', sizeof(buf));

int i=0;
char *ptr = &buf[0];

while (1) {
if (i == sizeof(buf))
break;

char byte = *ptr++; /* *** (1) *** */
printf("%c", byte);
++i;
}
printf("\n");
return 0;
}

// ----------- end code

In the last iteration of the loop, ptr will point past the last byte
of memory allocated for this array. This is a contrived example, but
for (ptr = buf; ptr < buf + sizeof(buf); ptr++)
putchar(*ptr);
is far less contrived, but it is perfectly equivalent.
I just wanted to know whether it's ok to point past the valid memory
for this array as long as I don't read or modify the contents of
memory at that address afterwards. On the surface it seems like this
code won't cause me any problems.
Yes, but only immediately past the last element. For example (buf + 10) is a valid pointer, even if you can't dereference it, but
(buf
+ 11) has undefined behaviour.
Jul 4 '07 #6

"tguclu" <tu**********@gmail.comha scritto nel messaggio news:11**********************@c77g2000hse.googlegr oups.com...
[top-posting fixed]
On Jul 4, 12:46 am, jois.de.vi...@gmail.com wrote:
>Hello, I was wondering if the following code was ok:

// ----------- start code

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

int main(int argc, char** argv)
{
char buf[10];
memset(buf, 'a', sizeof(buf));

int i=0;
char *ptr = &buf[0];
char *ptr = buf ; //this would do the same
>>
while (1) {
if (i == sizeof(buf))
break;

char byte = *ptr++; /* *** (1) *** */
printf("%c", byte);
++i;
}
printf("\n");
return 0;

}

// ----------- end code

In the last iteration of the loop, ptr will point past the last byte
of memory allocated for this array. This is a contrived example, but
I just wanted to know whether it's ok to point past the valid memory
for this array as long as I don't read or modify the contents of
memory at that address afterwards. On the surface it seems like this
code won't cause me any problems.
Hi,

If your concern by saying "point past the valid memory " is ,
Would it cause a problem to point an unallocated location ? Yes it
would. Because line notated by /* *** (1) *** */ , post-increases
ptr and in the final loop ptr will show next adjacent memory
location.But we did't allocate any place for this location and we
don't know what lies in it.

But looking at your implementation , this would cause no problem
because you don't use ptr anywhere else.
Only because it is just past the end of buf. If it were any
further, it'd cause UB. (Yes, I don't believe on your machine
that'd cause problems if you computed buf + 16 without ever
dereferencing it, but it's something I would not do on a DS9K.)
Jul 4 '07 #7

"pete" <pf*****@mindspring.comha scritto nel messaggio news:46***********@mindspring.com...
jo***********@gmail.com wrote:
> while (1) {
if (i == sizeof(buf))
break;

The non bizarre way of writing that, is:

while (i != sizeof(buf)) {
Or
for( ; i < sizeof buf ; ) {

and i = 0 before the loop and ++i at the end of its body can then
be moved to more appropriate places.
Jul 4 '07 #8
Yes, but only immediately past the last element. For example (buf + 10) is a valid pointer, even if you can't dereference it, but
(buf
+ 11) has undefined behaviour.
Why should this cause undefined behaviour if it is not accessed.
Pointer just happens to be another variable storing address instead of
any other data. As long as it stores data within its range (i.e. say
32-bit address) i dont think it should give undefined behaviour as
long as it is not accessed. In that case the following lines should
have undefined behaviour:

int *p = NULL; // points to 0, invalid mem
int *p; // store garbage address which may / may not be correct

(buff + 11) will just return a number. Thats it. Dont u think??

Regards,
Manish
(http://manishtomar.blogspot.com)

Jul 4 '07 #9
"Manish Tomar" <ma**********@gmail.comwrote in message
news:11**********************@i38g2000prf.googlegr oups.com...
>Yes, but only immediately past the last element. For example
(buf + 10) is a valid pointer, even if you can't dereference it,
but (buf + 11) has undefined behaviour.

Why should this cause undefined behaviour if it is not accessed.
Because the Standard says so.
Pointer just happens to be another variable storing address
instead of any other data. As long as it stores data within its
range (i.e. say 32-bit address) i dont think it should give
undefined behaviour as long as it is not accessed.
Perhaps that's how it works on _your_ implementation. There are others
where pointers have special registers and even the creation or assignment of
an invalid pointer causes a trap, whether you dereference it or not. C
allows that behavior.
In that case the following lines should
have undefined behaviour:

int *p = NULL; // points to 0, invalid mem
NULL is a special case specifically allowed by the Standard.
int *p; // store garbage address which may / may not be correct
If you do anything with p other than assign a valid address or NULL to it,
you get UB.
(buff + 11) will just return a number. Thats it. Dont u think??
No, the Standard says that's UB, and so it is.

Just because your implementation treats pointers and integers the same under
the hood (and thus lets you get away with all sorts of things) doesn't mean
that all do. C runs on a lot of systems that aren't so forgiving...

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Jul 4 '07 #10
Manish Tomar wrote:
>Yes, but only immediately past the last element. For example (buf + 10) is a valid pointer, even if you can't dereference it, but
(buf
+ 11) has undefined behaviour.

Why should this cause undefined behaviour if it is not accessed.
Because the standard says so.
Pointer just happens to be another variable storing address instead of
any other data.
On some machines, actual machines that have existed and have had C
implementations, the restrictions on pointers are stronger than that.

In some implementations, such as those intended for debugging support,
pointers are more than "just addresses", and computing out-of-range
pointers will raise some kind of error.
As long as it stores data within its range (i.e. say
32-bit address) i dont think it should give undefined behaviour as
long as it is not accessed.
Nevertheless, some machine architectures did/do check, and the
C standard allows them to do so.

Note that "has undefined beahviour" doesn't mean "traps". It means
that the implementation is allowed to do /anything/. It may trap.
It may wrap. It may return zeroes. The Standard doesn't place any
constraints on the implementation at all.
In that case the following lines should
have undefined behaviour:

int *p = NULL; // points to 0, invalid mem
It does /not/ "point to 0". It's a /null pointer/; it doesn't
point anywhere.
int *p; // store garbage address which may / may not be correct
It has an indeterminate value; any use of it invokes undefined
behaviour.
(buff + 11) will just return a number. Thats it. Dont u think??
I don't think so -- but an implementation can legally do so if
that's convenient for it.

--
Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Jul 4 '07 #11
Manish Tomar wrote, On 04/07/07 12:40:
>Yes, but only immediately past the last element. For example (buf + 10) is a valid pointer, even if you can't dereference it, but
(buf
+ 11) has undefined behaviour.

Why should this cause undefined behaviour if it is not accessed.
Because the C standard says it does. As a programmer you really do not
need to know more than that.
Pointer just happens to be another variable storing address instead of
any other data. As long as it stores data within its range (i.e. say
32-bit address) i dont think it should give undefined behaviour as
long as it is not accessed. In that case the following lines should
have undefined behaviour:

int *p = NULL; // points to 0, invalid mem
No, it is a null pointer, it might point to some address other than 0 or
it might be something that does not actually point to anywhere at all.
int *p; // store garbage address which may / may not be correct

(buff + 11) will just return a number. Thats it. Dont u think??
Address are not necessarily just numbers, and the standard is written
the way it is to allow for implementations which can generate hardware
traps on invalid pointer arithmetic, or even on just loading an invalid
pointer, and crashes your program.
--
Flash Gordon
Jul 4 '07 #12
On Jul 4, 12:40 pm, Manish Tomar <manish.to...@gmail.comwrote:
Yes, but only immediately past the last element. For example (buf + 10) is a valid pointer, even if you can't dereference it, but
(buf
+ 11) has undefined behaviour.

Why should this cause undefined behaviour if it is not accessed.
Pointer just happens to be another variable storing address instead of
any other data. As long as it stores data within its range (i.e. say
32-bit address) i dont think it should give undefined behaviour as
long as it is not accessed. In that case the following lines should
have undefined behaviour:

int *p = NULL; // points to 0, invalid mem
int *p; // store garbage address which may / may not be correct

(buff + 11) will just return a number. Thats it. Dont u think??
(buff + 11) will not return a number, because there is no return
statement, and it will not yield a number, because if anything, it
would yield a pointer. Programming requires exactness, don't you
think?

If "int *p = (buff + 11) doesn't invoke undefined behaviour, it must
be defined behaviour, right? So what is that behaviour? Would you say
that for example p != NULL must yield a value of 1 (true), and that p
buff must yield a value of 1? Now what if we replace 11 with a
different numbers, say 12, or 100000, or 4000000000? Do you still
think that p buffer must yield a value of 1? If not, where would
this change?

"Undefined behaviour" means: The behaviour is not defined by the C
Standard. It doesn't matter whether you can imagine how something
undesired happens or not, what matters is whether the behaviour is
defined or not.

Now take this is a little challenge: Give an reasonable scenario where
a highly optimising compiler produces a very unexpected result if a
pointer expression (p + 11) is evaluated.

Jul 4 '07 #13
christian.bau wrote:
Now take this is a little challenge: Give an reasonable scenario where
a highly optimising compiler produces a very unexpected result if a
pointer expression (p + 11) is evaluated.
#include <stdio.h>
#include <stdlib.h>

void g(void);

void f(void) {
char *p = malloc(10);
if (p == NULL) return;

p + 11;

for (;;) {
g();
printf("%c\n", p[10]);
}
}

void g(void) {
exit(0);
}

An optimising compiler may assume that because p+11 is evaluated, p+11 must
be a valid address, so p+10 must be dereferencable. As neither g nor printf
have any way of modifying p[10], the read of p[10] can be moved out of the
loop. And when p[10] is then evaluated, the program crashes.

A highly optimising compiler, on the other hand, would drop p entirely. :-)
Jul 4 '07 #14
Thanks a lot guys for the response :). I haven't read the standard and
I didnt think from C implementation point of view. Now, I am clear
with it.

Jul 5 '07 #15

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

Similar topics

2
by: Matthias Kaeppler | last post by:
Hello, I was wondering, does dereferencing past-the-end iterators yield undefined behavior? Especially, is the result of calling an STL algorithm on an empty range undefined? For example...
8
by: BigMan | last post by:
I wonder if the C++ standard says what should happen if I increment a pointer to a one-past-the-end value. I think it says that it is perfectly legal to increment a pointer to the last element...
23
by: Gautam | last post by:
this piece of code assigns an int pointer(evident) to a char, and when i try to access the ascii value of the char through the integer pointer(p) , what i get is a junk value or not i...
11
by: Sushil | last post by:
Hi Gurus I've tried to come up with a small logical example of my problem. The problem is platform specific (MIPS) which I understand should not be discussed here. So here goes my example: ...
7
by: Old Wolf | last post by:
For the following code: int main(void) { short a, *ptr; ptr = a + 100; ptr -= 0; }
12
by: spibou | last post by:
Why is a pointer allowed to point to one position past the end of an array but not to one position before the beginning of an array ? Is there any reason why the former is more useful than the...
16
by: mailforpr | last post by:
How do I do that? The thing is, the only information I have about the iterator is the iterator itself. No container it is belonging to or anything. Like template<Iteratorvoid...
4
by: John den Haan | last post by:
Hello! I was wondering how I can pass a pointer to a 2D-array (declared with a malloc-construct) as if it were a continuous 1D-array of the size (rows*cols)? Is this at all possible, and if so,...
7
by: william | last post by:
My question is: Specific memory block where my pointer pointing to changed strangely, seemingly that no statement changed it. Here are two examples I got: ***********1***************** I was...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.