Say if a function accessed this element in an array called c. What does it mean?
Printable View
Say if a function accessed this element in an array called c. What does it mean?
It is technically undefined, if c is an array. If c is a pointer INTO an array, then I think it is still undefined by the standard, but it's possible that it "works" correctly - getting the element BEFORE c.
--
Mats
c was a pointer so it did mean one element before. Thanks.
Citing from my copy of the standard:
I read this as "if c[-1] is an object of the same array as the one that contains c[0], then it's ok". Besides, the subscript operator in E1[E2] is defined as (*((E1) + (E2))) where E1 is a pointer and E2 is an integer.Quote:
J.2 Undefined behavior
The behavior is undefined in the following circumstances:
[...]
- Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.6).
Hence, the following should be ok:
Greets,Code:int a[8];
int *c = a + 4;
if(c[-1] == a[3])
puts("works");
Philip
In the case you site there then c[-1] is technically a valid statement. But if you have
then c[-1] would return an unknown value since that address isn't part of the array c. I think this is more in the nature of the original question.Code:int c[8];
So while c[-1] isn't undefined, except in the case you refer to, it is an unknown value.
I agree with snafuist. It should be fine and equal to *(a - 1)...
I don't think that is considered undefined behavior. c[-1] returns the "value" stored in the address that is one before c[0].
Although, I guess that if c[0] is stored on address "0" or the lowest possible address, then c[-1] would generate an error. Or of c[0] is one address after the end of system protected memory.
I append my original statement. c[-1] yields undefined behavior.
why will C compiler give error if you try to access a memory.....
the only differnece here is you haven't stored any value there...
it will definitely print some value...but it will be a GARBAGE.
Python....whereas prints the value of last element of array
...suppose i have array of 5 elements then a[-1] is equivalent to a[4]
...but thats in PYTHON
But if store some value there...it will print it
exampleCode:#include<stdio.h>
int main()
{
int c[] = {2,5,6,8,3,6};
c[-1] = 57;
printf("%d",c[-1]);
return 0;
}
Code:OUTPUT:
57
Yes you can do that, but you are likely to get a seg fault or other unexpected behavior if you do something like that.
Just because something works SOMETIMES doesn't mean it will work ALL times.
The memory you're writing to isn't allocated, so it's undefined.
Compiler doesn't play dice.....
Can u make out when does it give segmentation fault and when the garbage value...
You could be overwriting something important that is located in front of the array in memory?
Maybe, even probably. It might also reformat your hard disk drive or attempt to launch a nuke targeted at your location. Undefined behaviour, friend.Quote:
Originally Posted by Tanuj_Tanmay
Use the FAQ Luke!
Quzah.
It yields undefined behaviour, definitely, because the C standard says so.
Section J.2 of the 1999 C standard summarises many variants of undefined behaviour, one of which is;
Quote:
An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).
the reason why "someone" included the terminology of "bad programming practices" is because they are bad programming practices, hence, should be avoided. I see no reason to hold on to a very buggy c[-1] let alone to defend its use.
I agree, it should be used with extreme care. But how do you propose we'd solve the problem of malloc that stores a block of data stored BEFORE the actual pay-load data returned, and when we come to free, we need to find that block of data? Of course, we could have some sort of list of allocations and search that list for the passed in pointer. But some people certainly use some form like this:
Which is about the same as the c[-1] described above.Code:void free(void *p)
{
...
AdminBlock *pAdmin = ((AdminBlock *)p)-1;
...
--
Mats
Well, it's not actually.
Firstly, it is up the the implementation as to how it implements malloc() and free(). The purpose of implementation defined behaviour is to allow freedom for the implementation (the compiler, standard library, etc) .... the implementation can attach any meaning to undefined behaviour that makes sense to it.
Second, if free() behaves like you describe then malloc() and friends presumably do something like;
That addition of the offset (+1) in malloc() would ensure the negative offset (-1) within free() yields a valid address within the dynamically allocated memory/array. So no need to rely on undefined behaviour.Code:void *malloc(size_t n)
{
AdminBlock *buffer = (AdminBlock *)get_memory_from_system(n);
return (void *)(buffer + 1);
}
Grumpy, yes of course, we need a matching pair where malloc allocates a bit of extra memory, and then gives the address of something WIHTIN that block of memory, with enough space for the admin block BEFORE.
--
Mats