Stupid question about array boundries
Author |
Message |
Revolv #1 / 11
|
 Stupid question about array boundries
I was just looking through one of my C manuals and was reading up on array declarations. Book says that array[10] declares an array of 10 elements 0-9. If goes on to say that with an array of char, an array[10] gives space for an array of nine elements plus the '\0' char. The element with subscript 10 is beyond the allocated space for this array. Yet in programs I've coded, the element (not the declaration) 'array[10]' is an adressable element of the array, containing '\0' when the string is filled to capacity. What gives? I thought that array[10] was where '\0' was placed. I'm wrong, huh? But shouldn't this cause a memory violation?
|
Fri, 28 Sep 2001 03:00:00 GMT |
|
 |
Erik van Bronkhors #2 / 11
|
 Stupid question about array boundries
Not a stupid question, but I think it is inappropriate to post detailed answers that most everyone in the group already knows--to the entire group. In other words, give a true email address or don't expect an answer. Quote:
> I was just looking through one of my C manuals and was reading up on > array declarations. Book says that array[10] declares an array of 10 > elements 0-9. If goes on to say that with an array of char, an > array[10] gives space for an array of nine elements plus the '\0' > char. The element with subscript 10 is beyond the allocated space for > this array. Yet in programs I've coded, the element (not the > declaration) 'array[10]' is an adressable element of the array, > containing '\0' when the string is filled to capacity. What gives? I > thought that array[10] was where '\0' was placed. I'm wrong, huh? But > shouldn't this cause a memory violation?
-- Erik van Bronkhorst http://www.ridgenet.net/~zipper/ http://www.qsl.net/kc6uut "Trust the computer industry to shorten 'Year 2000' to 'Y2K.' It was this kind of thinking that caused the problem in the first place." The machine does not isolate man from the great problems of nature but plunges him more deeply into them. -- Antoine de Saint-Exupery, 'Wind, Sand, and Stars.'
|
Fri, 28 Sep 2001 03:00:00 GMT |
|
 |
Will Ro #3 / 11
|
 Stupid question about array boundries
: I was just looking through one of my C manuals and was reading up on : array declarations. Book says that array[10] declares an array of 10 : elements 0-9. If goes on to say that with an array of char, an : array[10] gives space for an array of nine elements plus the '\0' : char. The element with subscript 10 is beyond the allocated space for : this array. Yet in programs I've coded, the element (not the : declaration) 'array[10]' is an adressable element of the array, : containing '\0' when the string is filled to capacity. What gives? I : thought that array[10] was where '\0' was placed. I'm wrong, huh? But : shouldn't this cause a memory violation? You've been working on systems which round up memory allocations, or you haven't checked whatever variable follows the misallocated array in memory. I must admit, I'm suprised you've got away with it for any length of time. A character array of length ten can hold a string of maximum length nine in elements 0 to 8, with the last element, array[9], being nul. You can safely have a pointer which points to the element one beyond the end of the array, but you can't de-reference it. Will
|
Fri, 28 Sep 2001 03:00:00 GMT |
|
 |
Jplahm #4 / 11
|
 Stupid question about array boundries
Quote: (Revolver) writes: > But >shouldn't this cause a memory violation?
There are no memory violations in C unless you are using an operating system with protected memory. A good programming practice is to never hard code sizes in to the "C" line code. Instead, use sizeof() or #define. For example: #define MAX_STRING_SIZE 25 typedef char STRING[MAX_STRING_SIZE]; STRING s, s1; Now, to move between s1 and s, do: memcpy((void *) s, (void *) s1, MAX_STRING_SIZE); JPL
|
Fri, 28 Sep 2001 03:00:00 GMT |
|
 |
Kaz Kylhe #5 / 11
|
 Stupid question about array boundries
Quote:
>(Revolver) writes: >> But >>shouldn't this cause a memory violation? >There are no memory violations in C unless you are using an operating system >with protected memory. A good programming practice is to never hard code sizes >in to the "C" line code. Instead, use sizeof() or #define. For example: >#define MAX_STRING_SIZE 25 >typedef char STRING[MAX_STRING_SIZE];
Creating typedefs for arrays requires caution. When you do so, avoid trying to pass the resulting type into functions. For example, suppose you now write: process_string(STRING s) { /*...*/ } It looks harmless enough, but the parameter 's' has been secretly converted to char * type. Hence sizeof 's' is not the same as sizeof(STRING), for instance. I find such typedefs handy for defining specific data types, for example: typedef char user_name_t[64]; typedef char pass_phrase_t[128]; These types can then appear in distinct, but related, data structures, ensuring that everything is compatible: that, for instance, one user ID can always be copied to another with an unchecked, fixed-size memcpy(). When I use such typedefs, I try always to treat such types opaquely and pass around pointers to them, e.g. unsigned long pass_phrase_hash(pass_phrase_t *pp) { /* * use ``sizeof (*pp)'' here as needed * ... */ } Quote: >STRING s, s1; >Now, >to move between s1 and s, do: >memcpy((void *) s, (void *) s1, MAX_STRING_SIZE);
These casts are unncessary; because the first and second parameters of memcpy have void * type, the conversion takes place automatically. By putting in the cast, you may hide a potential error; for example, what if 's' points at the first element of an array of const chars? Your (void *) type casts away the constness, suppressing a compiler diagnostic. Also, since you went to all the trouble to create the STRING array typedef, why not take advantage of it and use sizeof instead of MAX_STRING_SIZE? memcpy(s, s1, sizeof s);
|
Fri, 28 Sep 2001 03:00:00 GMT |
|
 |
Sunil Ra #6 / 11
|
 Stupid question about array boundries
Quote: >I was just looking through one of my C manuals and was reading up on >array declarations. Book says that array[10] declares an array of 10 >elements 0-9. If goes on to say that with an array of char, an >array[10] gives space for an array of nine elements plus the '\0' >char. The element with subscript 10 is beyond the allocated space for >this array.
That's right. Quote: >Yet in programs I've coded, the element (not the >declaration) 'array[10]' is an adressable element of the array, >containing '\0' when the string is filled to capacity.
In some cases you might be able to do this - it's at the discretion of your compiler and your OS. You must not depend on this. Quote: >What gives? I >thought that array[10] was where '\0' was placed.
No. It can placed anywhere from array[0] to array[9], depending on how long the string you place in array is. Quote: >I'm wrong, huh? But >shouldn't this cause a memory violation?
It might well do sometimes. The C standard specifies that array[10] must be a valid address in memory, but doesn't say that you will be able to write to it (or read from it, for that matter). -- { Sunil Rao } "Is there any light more becoming than that, low and richly tinted, that comes subdued through the mists of sunshine?" -- J Sheridan Le Fanu
|
Wed, 03 Oct 2001 03:00:00 GMT |
|
 |
david thompso #7 / 11
|
 Stupid question about array boundries
Sat, 17 Apr 1999 22:32:41 +0100,
[ about accessing off-the-end-of char array[10] ] Quote: > >shouldn't this cause a memory violation? > It might well do sometimes. The C standard specifies that array[10] must > be a valid address in memory, but doesn't say that you will be able to > write to it (or read from it, for that matter).
If you mean array + 10, yes it is a "valid" pointer value in the sense that you can compute it, save it, pass it, etc., and use it to compute a pointer (back) to a valid array element; but dereferencing it (either read or write) is undefined. 6.3.6. In the real world it would usually be very costly to have memory protection this fine grained and I have never seen an implementation that signals a "violation" for this error. In practice reading off the end of an array will almost always silently return garbage or zero, and writing will often silently clobber some other variable, which may cause other parts of your program later to do almost anything from giving slightly wrong results to crashing. The only case likely to be caught by hardware is if array happens to be the very last static-duration object in your link image, and on many platforms only if it falls on a page boundary (maybe 4K or 16K), or the last auto on an upward-growing stack. If you mean & array [10], which most programmers expect to be the same, this is specified to be &*(array+10), which formally is undefined because of the dereference. This has been debated at length in the past; see dejanews. But since any reasonable implementation can compute this without doing the dereference, there seem no reliable reports of this actually failing "in the wild", and C9X will have a change (in 6.5.3.2/3) that specifies the &* to be effectively elided and makes this case (also) legal. (CCed) david.thompson at but not for trintech.com
|
Sat, 06 Oct 2001 03:00:00 GMT |
|
 |
Sunil Ra #8 / 11
|
 Stupid question about array boundries
Quote: >Sat, 17 Apr 1999 22:32:41 +0100,
>[ about accessing off-the-end-of char array[10] ] >> >shouldn't this cause a memory violation? >> It might well do sometimes. The C standard specifies that array[10] must >> be a valid address in memory, but doesn't say that you will be able to >> write to it (or read from it, for that matter).
<snip> Quote: >If you mean & array [10], which most programmers expect >to be the same, this is specified to be &*(array+10), >which formally is undefined because of the dereference.
No, this wasn't what I was referring to. I was talking about the first issue. -- { Sunil Rao } "Is there any light more becoming than that, low and richly tinted, that comes subdued through the mists of sunshine?" -- J Sheridan Le Fanu
|
Sat, 06 Oct 2001 03:00:00 GMT |
|
|
|