473,387 Members | 1,548 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,387 software developers and data experts.

Negative indices to a vector: Valid?


Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
ptr = &storage[N/2];
...
...
...
free(storage);
Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour? Or should the index operator only be given unsigned
arguments?

I have tried using a couple of different compilers on Linux and IRIX,
and it seems to work, but it does give me a slightly queasy feeling.
Regards

Joakim

--
Joakim Hove
hove AT ntnu.no /
Tlf: +47 (55 5)8 27 13 / Stabburveien 18
Fax: +47 (55 5)8 94 40 / N-5231 Paradis
http://www.ift.uib.no/~hove/ / 55 91 28 18 / 92 68 57 04
Dec 22 '05 #1
8 5145
This is perfectly legal. The array index is treated as a signed integer
in C.

a[i] is a shorthand way of writing
a + sizeof(a)*i

Thus if i is negative, the final entry addressed would be before a[0].

--
EventStudio System Designer 2.5 - http://www.EventHelix.com/EventStudio
Sequence Diagram Based Real-time and Embedded System Design Tool

Dec 22 '05 #2
Joakim Hove wrote:
Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
All bits 0 (which is what calloc provides) is *not* guaranteed to
represent a floating point 0, it could even be a trap representation.
Also, using "sizeof *storage" would be better than "sizeof(double)"
because if the type ever changes (say, to long double) then you will
still get the correct amount of space.
ptr = &storage[N/2];
...
...
...
free(storage);
Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour? Or should the index operator only be given unsigned
arguments?
What you are doing is completely legal. You could even do it if you were
using an array. Obviously, you have to be careful to ensure you don't go
off the end of the allocated space which can require a little more thought.
I have tried using a couple of different compilers on Linux and IRIX,
and it seems to work, but it does give me a slightly queasy feeling.


You are right to ask rather than relying on experimental results, since
there are "illegal" things that will "work" on some platforms but fail
on others, one of the classic (IMHO) examples of this being modifying
string literals.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 22 '05 #3
Joakim Hove wrote:

Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
ptr = &storage[N/2];
...
...
...
free(storage);

Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour?


Only if by "Now", you mean before:

free(storage);

--
pete
Dec 22 '05 #4
Joakim Hove wrote:
Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
ptr = &storage[N/2];
...
...
...
free(storage);
Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour? Or should the index operator only be given unsigned
arguments?


Legal, provided N is odd (as shown).

However, do not be fooled into thinking that "just any"
offset will work. The above is all right because `ptr' does
in fact point into the allocated area. The language guarantees
that `ptr = &storage[k]' will work for all k between 0 and N
(inclusive at both ends), but not for k outside that range.
You may occasionally encounter `ptr = &storage[-1]' as part of
an attempt to imitate the 1-based arrays of Fortran, say, but
such code is incorrect and need not work at all.

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 22 '05 #5
>This is perfectly legal. The array index is treated as a signed integer
in C.

a[i] is a shorthand way of writing
a + sizeof(a)*i


No, a[i] is a shorthand way of writing *(a + i). It's also equivalent
to i[a].

It may also be considered as a shorthand way of writing
*(a addl (sizeof(a) * i)), where addl is an assembly-language
addition operator.

It is allowed for i to be negative provided the storage referred
to exists.

Gordon L. Burditt
Dec 22 '05 #6
Gordon Burditt wrote:
This is perfectly legal. The array index is treated as a signed integer
in C.

a[i] is a shorthand way of writing
a + sizeof(a)*i
No, a[i] is a shorthand way of writing *(a + i). It's also equivalent
to i[a].


Yes.
It may also be considered as a shorthand way of writing
*(a addl (sizeof(a) * i)), where addl is an assembly-language
addition operator.


I think it should be sizeof(*a), instead of sizeof a.

--
pete
Dec 22 '05 #7

Thanks to all of you who answered. It makes my code look much nicer,
so I am grateful that I can rely on this approach.
Joakim

--
Joakim Hove
hove AT ntnu.no /
Tlf: +47 (55 5)8 27 13 / Stabburveien 18
Fax: +47 (55 5)8 94 40 / N-5231 Paradis
http://www.ift.uib.no/~hove/ / 55 91 28 18 / 92 68 57 04
Dec 22 '05 #8
> No, a[i] is a shorthand way of writing *(a + i). It's also equivalent
to i[a].


Agreed. Pointer arithmatic internally multiples to take care of the
sizeof.

--
EventStudio System Designer 2.5 - http://www.EventHelix.com/EventStudio
Sequence Diagram Based System Design and Object Modeling Tool

Dec 24 '05 #9

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

Similar topics

8
by: dan | last post by:
I was recently surprised, and quite shocked in fact, to find that Python treats negative indices into sequence types as if they were mod(length-of-sequence), at least up to -len(seq). This fact...
19
by: David Abrahams | last post by:
Can anyone explain the logic behind the behavior of list slicing with negative strides? For example: >>> print range(10) I found this result very surprising, and would just like to see the...
5
by: Ross MacGregor | last post by:
I have a very simple yet complicated problem. I want to generate a random list of indices (int's) for a container. Let's say I have a container with 10 items and I want a list of 3 random...
11
by: Steve | last post by:
Hi, I'm using a std::vector to store a list of user defined objects. The vector may have well over 1000 elements, and I'm suffering a performance hit. If I use push_back I get a much worse...
4
by: slurper | last post by:
tx for answer Bazarov i have another problem i have a vector with 20 elements in it (20 ints). i'd like to have the elements sorted in ascending order, but somehow i need to know what index...
1
by: illegal.prime | last post by:
So I see from the documentation here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemCollectionsArrayListClassBinarySearchTopic.asp That the code uses the...
11
by: drtimhill | last post by:
I'm just starting out on Python, and am stumped by what appears an oddity in the way negative indices are handled. For example, to get the last character in a string, I can enter "x". To get the...
2
by: smichr | last post by:
It seems to me that the indices() method for slices is could be improved. Right now it gives back concrete indices for a range of length n. That is, it does not return any None values. Using an...
2
by: ajcppmod | last post by:
I'm really confused about results of slices with negative strides. For example I would have then thought of the contents of mystr as: indices 0 1 2 3 4 5 6 7 8 content m y s t r i n...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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: 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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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...

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.