473,656 Members | 2,793 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

is &(vector[0]) always valid?


I was under the impression that the following was always valid:

std::vector<Tv;
..
T *p = &(v[0]);

But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.

I'm hoping that the above expression is fine, even if v is empty, but
that if you try to dereference p, you're in trouble.

If the above isn't ok, I'd have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;

I took a look in the C++98 standard, and couldn't find anything to
confirm my hope. I see from Table 68 that the expression has the
"operationa l sematics" of

&(*(v.begin( ) + 0))

which sure *seems* like it might in turn be "operationa lly equivalent"
to v.begin(), which sure seems safe, even for an empty vector. But I
now feel myself to be on very thin ice.

So, can I write:

T *p = &(v[0]);

or do I have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;

Thanks,
John Salmon

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #1
18 2949
John Salmon wrote:
I was under the impression that the following was always valid:

std::vector<Tv;
.
T *p = &(v[0]);

But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.

I'm hoping that the above expression is fine, even if v is empty, but
that if you try to dereference p, you're in trouble.
It may work on your platform, however the C++ standard says it's
undefined. Hence, it may work for you today but it may also break tomorrow.
>
If the above isn't ok, I'd have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;
Right.
Jan 20 '07 #2
John Salmon wrote:
I was under the impression that the following was always valid:

std::vector<Tv;
.
T *p = &(v[0]);

But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.

I'm hoping that the above expression is fine, even if v is empty, but
that if you try to dereference p, you're in trouble.

If the above isn't ok, I'd have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;

I took a look in the C++98 standard, and couldn't find anything to
confirm my hope. I see from Table 68 that the expression has the
"operationa l sematics" of

&(*(v.begin( ) + 0))

which sure *seems* like it might in turn be "operationa lly equivalent"
to v.begin(), which sure seems safe, even for an empty vector. But I
now feel myself to be on very thin ice.

So, can I write:

T *p = &(v[0]);

or do I have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;

Thanks,
John Salmon
v[0] is NOT valid for an empty vector, and therefore &v[0] is not valid
either. You are right about the operational semantics, but neither is
that expression valid. If the vector is empty, then begin() == end(),
and you are therefore "dereferenc ing" the end() iterator.

As for the alternate expression you propose, using empty() rather than
size() would be more idiomatic, and might be more efficient, depending
on the implementation:

T *p = v.empty() ? 0 : &(v[0]) ;

--
Alan Johnson

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #3
In article <m3************ @river.fishnet> , John Salmon
<js*****@thesal mons.orgwrote:
I was under the impression that the following was always valid:

std::vector<Tv;
.
T *p = &(v[0]);

But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.
its not valid if v.size()==0.
template <class T,class A>
inline T *data(std::vect or<T,A&v)
{
return v.empty() ? 0: &v[0];
}
is an easy work around. Recent drafts of the standard provide
vector with a data() member function which does this, but your
implementation probably does not.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #4
On Sat, 20 Jan 2007 07:21:08 GMT, John Salmon wrote:
>So, can I write:

T *p = &(v[0]);

or do I have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;
What would be the address of the first element of an empty vector?

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #5
John Salmon wrote:
>
I was under the impression that the following was always valid:

std::vector<Tv;
.
T *p = &(v[0]);

But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.

I'm hoping that the above expression is fine, even if v is empty, but
that if you try to dereference p, you're in trouble.
If v is empty, once you evaluate v[0] you have undefined behavior. More
importantly, an implementation of std::vector<is perfectly free and maybe
even well-advised to do something like:

T& operator[] ( size_type i ) {
assert( i < this->size() );
return( this->data[i] );
}

Because of the assert(), your program could crash depending on compilation
options.
If the above isn't ok, I'd have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;

I took a look in the C++98 standard, and couldn't find anything to
confirm my hope. I see from Table 68 that the expression has the
"operationa l sematics" of

&(*(v.begin( ) + 0))

which sure *seems* like it might in turn be "operationa lly equivalent"
to v.begin(), which sure seems safe, even for an empty vector. But I
now feel myself to be on very thin ice.

So, can I write:

T *p = &(v[0]);

or do I have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;
Why do you insist on using T* anyway? What is the reason not to use
std::vector<T>: :iterator?
Best

Kai-Uwe Bux

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #6
"John Salmon" <js*****@thesal mons.orgwrote in message
news:m3******** ****@river.fish net...
I was under the impression that the following was always valid:
std::vector<Tv;
T *p = &(v[0]);
But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.
Whoever told you that is correct.
I'm hoping that the above expression is fine, even if v is empty, but
that if you try to dereference p, you're in trouble.
Sorry to dash your hopes, but...
If the above isn't ok, I'd have to write:
T *p = (v.size()!=0)? &(v[0]) : 0;
Right.
>
I took a look in the C++98 standard, and couldn't find anything to
confirm my hope. I see from Table 68 that the expression has the
"operationa l sematics" of

&(*(v.begin( ) + 0))

which sure *seems* like it might in turn be "operationa lly equivalent"
to v.begin(), which sure seems safe, even for an empty vector. But I
now feel myself to be on very thin ice.
You are. v.begin() + 0 is always equivalent to v.begin(), but &(*v.begin() )
is undefined if v is empty.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #7
In article <m3************ @river.fishnet> , John Salmon
<js*****@thesal mons.orgwrites
>I was under the impression that the following was always valid:

std::vector<Tv ;
.
T *p = &(v[0]);

But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.
You were correctly informed. The problem is that v[0] has undefined
behaviour if there are no elements. That means that &(v[0]) has
undefined behaviour. This is not that unreasonable because an empty
vector does not have a location for any element so there will be no
address.

Changing this would have required a special rule for &(v[0]). Instead
you must write something like:

T *p = v.size() ? &(v[0]) : 0;

If there is any possibility that v is an empty vector. (There are
several variations on the above definition but I tend to use a limited
subset of the member functions of vector rather than remember the exact
spelling of all of them.)
--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #8
John Salmon wrote:
I was under the impression that the following was always valid:
std::vector<Tv;
.
T *p = &(v[0]);
But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.
I'm hoping that the above expression is fine, even if v is empty,
It's not. It's undefined behavior, and will core dump on some
implementations . (It core dumps with g++ 4.0.1, for example, or
with VC++ 8.)
but that if you try to dereference p, you're in trouble.
If the above isn't ok, I'd have to write:
T *p = (v.size()!=0)? &(v[0]) : 0;
I took a look in the C++98 standard, and couldn't find anything to
confirm my hope. I see from Table 68 that the expression has the
"operationa l sematics" of
&(*(v.begin( ) + 0))
No. The expression a[n] is the equivalent of *(v.begin() + 0)
(which is presumably the equivalent of *v.begin()). If
v.begin() == v.end(), however, *v.begin() is undefined behavior.
which sure *seems* like it might in turn be "operationa lly equivalent"
to v.begin(), which sure seems safe, even for an empty vector. But I
now feel myself to be on very thin ice.
I'd say that the ice has already broken. Your code causes a
run-time error (core dump, or its moral equivalent under
Windows) with two of the three compilers I regularly use.
So, can I write:
T *p = &(v[0]);
or do I have to write:
T *p = (v.size()!=0)? &(v[0]) : 0;
The latter.

Given the particular guarantee for std::vector, I wonder if an
additional member function, data() might not be in order. A
function which could be required to return a null pointer if the
vector is empty.

--
James Kanze (Gabi Software) email: ja*********@gma il.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #9
John Salmon wrote:
I was under the impression that the following was always valid:

std::vector<Tv;
.
T *p = &(v[0]);

But I was recently told that care was needed in case the vector was
empty, i.e., when v.size() == 0.

I'm hoping that the above expression is fine, even if v is empty, but
that if you try to dereference p, you're in trouble.

If the above isn't ok, I'd have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;

I took a look in the C++98 standard, and couldn't find anything to
confirm my hope. I see from Table 68 that the expression has the
"operationa l sematics" of

&(*(v.begin( ) + 0))

which sure *seems* like it might in turn be "operationa lly equivalent"
to v.begin(), which sure seems safe, even for an empty vector. But I
now feel myself to be on very thin ice.

So, can I write:

T *p = &(v[0]);

or do I have to write:

T *p = (v.size()!=0)? &(v[0]) : 0;

Thanks,
John Salmon

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Yes, it's undefined.

v[0] is equivalent to *v.begin(). Whether v is an empty vector or not,
v.begin() returns a valid iterator. But if v is empty, v.begin(), like
v.end(), is not a valid dereferenceable iterator, so *v.begin() is
undefined.

Note though, &(*(v.begin( ) + 0)) is not, as you said, "operationa lly
equivalent" to v.begin() because v.begin() returns an object of the
vector<T>'s iterator type while &(*(v.begin( ) + 0)) should return a
type of pointer to T (since operator * is overloaded here), and the
iterator type needs not to be the same as a pointer to T.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Jan 20 '07 #10

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

Similar topics

2
5938
by: lf | last post by:
If I want to get a pointer to the initial data element in a vector<double>, does it make any difference whether I use (for vector<double> v) double* pVec1 = &v; or double* pVec2 = &v.front(); The intention is to pass the pointer to a function that expects such type. I vaguely remember someone recommended the second approach, but why?
72
4187
by: Paminu | last post by:
In math this expression: (a < b) && (b < c) would be described as: a < b < c But why is it that in C these two expressions evaluate to something different for the same values of a, b and c?
8
1594
by: Gemma Fletcher | last post by:
Hi all :) I'm implementing a menu system for my assignment. User inputs command & an if/else switch statement executes the command. I'm just not quite sure the best way to take user input. For eg: L <vehicleId>
3
2088
by: Shoregill | last post by:
Hi I've been trying to validate my CSS at W3C's validator and get the following response: No error or warning found To work as intended, your CSS style sheet needs a correct document parse tree. This means you should use valid HTML. My XHTML validates fine, and I've checked and rechecked my CSS code and have hit a total blank, can anybody help? Any suggestions will be most gratefully welcome. My CSS code is
2
2180
by: Arpan | last post by:
I came across the following statement at http://windowssdk.msdn.microsoft.com/en-us/library/hdf992b8.aspx: Although an XML document is considered to be well formed if it meets all the syntactical requirements defined by the World Wide Web Consortium (W3C) Extensible Markup Language (XML) 1.0 Recommendation, it is not considered valid unless it is well formed and also conforms to the constraints defined by its DTD or schema. Therefore,...
9
1849
by: miaohua1982 | last post by:
the program is as follows: #include <vector> using namespace std; class A{}; int main() { A* const &p = NULL; vector<A*B(3,NULL); //there is a compile error B.push_back(NULL);
5
1951
by: Numeromancer | last post by:
From the C++-FAQ Lite: http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3 ---------------------------- 34.3] Is the storage for a std::vector<Tguaranteed to be contiguous? Yes. This means you the following technique is safe: #include <vector>
8
1426
by: Ioannis Vranos | last post by:
C++03: Is it always guaranteed that in vector: vector<intvec(10); &vec always points to the first element of the array, for vec.size()0?
0
8382
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8600
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7311
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6162
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5629
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4150
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4300
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1930
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1600
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.