I have char *array and it is dinamically alocated....
When I pass it to other function, I need to determine size of this array....
Problem: sizeof operator does not work with dinamically alocated
arrays!?!?!
How can I determine size of dinamically alocated array.... ?
Please advice...
Thx! 32 2597
Mateo wrote: I have char *array and it is dinamically alocated.... When I pass it to other function, I need to determine size of this array.... Problem: sizeof operator does not work with dinamically alocated arrays!?!?!
How can I determine size of dinamically alocated array.... ?
You cannot. You need to store the size at the time of allocation
and pass it into the same function. If you can't do that, do not
use a plain char array, use 'std::string'.
V
--
Please remove capital As from my address when replying by mail
Mateo wrote: I have char *array and it is dinamically alocated.... When I pass it to other function, I need to determine size of this array.... Problem: sizeof operator does not work with dinamically alocated arrays!?!?!
How can I determine size of dinamically alocated array.... ?
This is a Frequently Asked Question, but I don't know if it's in the FAQ.
The answer is you should use an std::vector<> unless you actually need a
primitive array, returned by new[].
If you have a legitimate reason not to use std::vector<>, then pass the size
with the array.
There's no portable way to get this information, because your program is
essentially throwing the information away after the new[] call. Don't.
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Phlip wrote: The answer is you should use an std::vector<> unless you actually need a primitive array, returned by new[].
Not to mention that for passing to library/OS routines that require a
naked T*, a std::vector<T> is trivially convertable to a T* by passing
&v[0].
Victor Bazarov wrote in message ... Mateo wrote: I have char *array and it is dinamically alocated.... When I pass it to other function, I need to determine size of this array.... Problem: sizeof operator does not work with dinamically alocated arrays!?!?!
How can I determine size of dinamically alocated array.... ?
You cannot. You need to store the size at the time of allocation and pass it into the same function. If you can't do that, do not use a plain char array, use 'std::string'. V --
Well, there's always the 'Three Stooges' method:
size_t SomeFunc( char /* const */ *MyCharArray ){
std::string ForSize( MyCharArray );
size_t ArrSize( ForSize.size() );
// Do something with MyCharArray that needs size.
// don't forget to add 1 if you need to include
// the '\0' at end of array.
return ArrSize;
// size_t ArrSize = sizeof( MyCharArray );
// return ArrSize; // returns 4 (the size of pointer)
}
int main(){
char MyCharArray[] = "abcd1234xyz";
std::cout<<"SomeFunc( MyCharArray ); "
<<SomeFunc( MyCharArray )<<std::endl;
return 0;
}
// output: SomeFunc( MyCharArray ); 11
--
Bob <G> R
POVrookie
BobR wrote: Victor Bazarov wrote in message ... Mateo wrote: I have char *array and it is dinamically alocated.... When I pass it to other function, I need to determine size of this array.... Problem: sizeof operator does not work with dinamically alocated arrays!?!?!
How can I determine size of dinamically alocated array.... ?
You cannot. You need to store the size at the time of allocation and pass it into the same function. If you can't do that, do not use a plain char array, use 'std::string'. V --
Well, there's always the 'Three Stooges' method:
size_t SomeFunc( char /* const */ *MyCharArray ){ std::string ForSize( MyCharArray ); size_t ArrSize( ForSize.size() ); // Do something with MyCharArray that needs size. // don't forget to add 1 if you need to include // the '\0' at end of array. return ArrSize; // size_t ArrSize = sizeof( MyCharArray ); // return ArrSize; // returns 4 (the size of pointer) }
int main(){ char MyCharArray[] = "abcd1234xyz"; std::cout<<"SomeFunc( MyCharArray ); " <<SomeFunc( MyCharArray )<<std::endl; return 0; } // output: SomeFunc( MyCharArray ); 11
I believe you've confused the size of the array with the length of
a C string stored in it. Show it again with this 'MyCharArray':
int main() {
char MyCharArray[] = "abc\0def\0ghi\0jkl\0\0\0";
...
V
--
Please remove capital As from my address when replying by mail
Victor Bazarov wrote in message ... BobR wrote: Victor Bazarov wrote in message ... Mateo wrote:
[snip] How can I determine size of dinamically alocated array.... ?
You cannot. You need to store the size at the time of allocation and pass it into the same function. If you can't do that, do not use a plain char array, use 'std::string'. V --
Well, there's always the 'Three Stooges' method:
size_t SomeFunc( char /* const */ *MyCharArray ){ std::string ForSize( MyCharArray ); size_t ArrSize( ForSize.size() ); // Do something with MyCharArray that needs size. return ArrSize; }
int main(){ char MyCharArray[] = "abcd1234xyz"; std::cout<<"SomeFunc( MyCharArray ); " <<SomeFunc( MyCharArray )<<std::endl; return 0; } // output: SomeFunc( MyCharArray ); 11
I believe you've confused the size of the array with the length of a C string stored in it. Show it again with this 'MyCharArray':
int main() { char MyCharArray[] = "abc\0def\0ghi\0jkl\0\0\0"; ... V --
Well, there's always the 'Three Stooges + Mickey Mouse' method: <G>
size_t SomeFunc2( char *MyCharArray ){
std::string ForSize( MyCharArray ); // the Mickey
std::string Look(3, '\0'); // the Mouse
size_t index( ForSize.size() );
while( ForSize.find( Look ) == std::string::npos ){
ForSize.push_back( MyCharArray[index] );
++index;
}
size_t ArrSize( ForSize.size() );
// Do something with MyCharArray.
return ArrSize;
}
int main(){
char MyCharArray[] = "abc\0def\0ghi\0jkl\0\0\0";
std::cout<<"SomeFunc2( MyCharArray ); "
<<SomeFunc2( MyCharArray )<<std::endl;
std::cout<<"sizeof(MyCharArray)/sizeof(*MyCharArray) "
<<sizeof(MyCharArray)/sizeof(*MyCharArray)<<std::endl;
return 0;
}
// -- output --
// SomeFunc2( MyCharArray ); 18
// sizeof(MyCharArray)/sizeof(*MyCharArray) 19
Either:
a - You have no sense of humor.
or
b - I've been had, and I tip my hat to you.
--
Bob R
POVrookie
Vector is the way to go.
I have read in Meyers that &v[0] is not advisable unless v.size () > 0.
red floyd wrote: Phlip wrote: The answer is you should use an std::vector<> unless you actually need a primitive array, returned by new[].
Not to mention that for passing to library/OS routines that require a naked T*, a std::vector<T> is trivially convertable to a T* by passing &v[0].
AnonMail2005 wrote: Vector is the way to go.
I have read in Meyers that &v[0] is not advisable unless v.size () > 0.
To the intermediates:
Bow before /C++ Coding Standards : 101 Rules, Guidelines, and Best
Practices/ (C++ in Depth Series) by Herb Sutter & Andrei Alexandrescu. It
covers such scratchy situations as interfacing to a C API that likes raw
pointers.
They advise the &v[0] trick, and I can't recall if they warn about the
size() == 0 situation.
Now I thought that all containers always have a valid .begin() and .end(),
and if they equal then the container is empty, so this might suggest that
&v[0] is always valid (whereas v[0] is not, because it dereferences an
unconstructed object).
So where am I wrong?
To the newbies:
The original poster appeared to be writing their own function that takes a
pointer. If so, they should avoid pointers (as should coders at all levels),
and should pass a reference to a vector:
typedef std::vector<int> ints_type;
void foo(ints_type & ints);
References have fewer features, so they are always better than pointers, and
vectors have more features than arrays, so they are always better than
arrays.
Always pick the technique with fewer features. Or more features. I'll try
again.
Always pick the technique with the safest features. Raw pointers have many
unsafe features, and vectors have many safe ones.
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Mateo posted: I have char *array and it is dinamically alocated.... When I pass it to other function, I need to determine size of this array.... Problem: sizeof operator does not work with dinamically alocated arrays!?!?!
How can I determine size of dinamically alocated array.... ?
Please advice... Thx!
#include <cstddef>
#include <iostream>
using std::cout;
using std::endl;
template<std::size_t i>
void PrintStringLength( char (&str)[i] )
{
cout << "This string is " << (i - 1) << " characters long.\n";
}
int main()
{
char (&str)[7] = * reinterpret_cast< char (*)[7] > ( new char[7] );
std::strcpy(str, "monkey");
PrintStringLength(str);
}
-Tomás
delete [] reinterpret_cast< char * > ( &str );
Tomás wrote: delete [] reinterpret_cast< char * > ( &str );
More than enough rope to shoot your foot off, huh? ;-)
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
I refer you to the relevant part of the FAQ for the time being since
all of my C++ books are at work: http://www.parashift.com/c++-faq-lit....html#faq-34.3
Phlip wrote: AnonMail2005 wrote:
Vector is the way to go.
I have read in Meyers that &v[0] is not advisable unless v.size () > 0.
To the intermediates:
Bow before /C++ Coding Standards : 101 Rules, Guidelines, and Best Practices/ (C++ in Depth Series) by Herb Sutter & Andrei Alexandrescu. It covers such scratchy situations as interfacing to a C API that likes raw pointers.
They advise the &v[0] trick, and I can't recall if they warn about the size() == 0 situation.
Now I thought that all containers always have a valid .begin() and .end(), and if they equal then the container is empty, so this might suggest that &v[0] is always valid (whereas v[0] is not, because it dereferences an unconstructed object).
So where am I wrong?
To the newbies:
The original poster appeared to be writing their own function that takes a pointer. If so, they should avoid pointers (as should coders at all levels), and should pass a reference to a vector:
typedef std::vector<int> ints_type; void foo(ints_type & ints);
References have fewer features, so they are always better than pointers, and vectors have more features than arrays, so they are always better than arrays.
Always pick the technique with fewer features. Or more features. I'll try again.
Always pick the technique with the safest features. Raw pointers have many unsafe features, and vectors have many safe ones.
-- Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
AnonMail2005 wrote: I refer you to the relevant part of the FAQ for the time being since all of my C++ books are at work: http://www.parashift.com/c++-faq-lit....html#faq-34.3 Now I thought that all containers always have a valid .begin() and .end(), and if they equal then the container is empty, so this might suggest that &v[0] is always valid (whereas v[0] is not, because it dereferences an unconstructed object).
Contiguity is a different topic - and yes it permits the &v[0] trick when
..size() > 0. Here's why this is important.
char * foo = new[42];
bar(foo);
// code that might throw
delete[] foo;
To make that more leak-safe, we could wrap foo in a boost::shared_array<> to
make it exception-safe (and take out the delete[] foo). Yet that would leave
foo without the many other benefits of being a vector.
Before a recent revision to The Standard, all vectors were secretely arrays,
so the bar(&foo[0]) trick worked, but The Standard didn't guarantee
contiguity of elements, so the trick was unstable. A program could
conceivably recompile with a version of the Standard Library that didn't
make vectors contiguous, and the compiler would not emit a diagnostic.
My question was whether all containers have a valid .begin() and .end(), and
if so does v[0] fit the rule "you can access one off the end of a container"
even if the container is empty.
Of course live code should just check for size() first (or add a dummy
element, etc.). I'm curious about the language law.
-- Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
That part of the fact addresses the &v[0] question if you read it in
it's entirety.
v.begin () and v.end (), of course are valid. But you can't
dereference (i.e. access) v.end (). And since v.begin () ==
v.end () for an empty vector, why would you think you could
derefernce v.begin () for an empty vector?
Phlip wrote: AnonMail2005 wrote:
I refer you to the relevant part of the FAQ for the time being since all of my C++ books are at work: http://www.parashift.com/c++-faq-lit....html#faq-34.3
Now I thought that all containers always have a valid .begin() and .end(), and if they equal then the container is empty, so this might suggest that &v[0] is always valid (whereas v[0] is not, because it dereferences an unconstructed object). Contiguity is a different topic - and yes it permits the &v[0] trick when .size() > 0. Here's why this is important.
char * foo = new[42]; bar(foo); // code that might throw delete[] foo;
To make that more leak-safe, we could wrap foo in a boost::shared_array<> to make it exception-safe (and take out the delete[] foo). Yet that would leave foo without the many other benefits of being a vector.
Before a recent revision to The Standard, all vectors were secretely arrays, so the bar(&foo[0]) trick worked, but The Standard didn't guarantee contiguity of elements, so the trick was unstable. A program could conceivably recompile with a version of the Standard Library that didn't make vectors contiguous, and the compiler would not emit a diagnostic.
My question was whether all containers have a valid .begin() and .end(), and if so does v[0] fit the rule "you can access one off the end of a container" even if the container is empty.
Of course live code should just check for size() first (or add a dummy element, etc.). I'm curious about the language law. -- Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
I refer you to the relevant part of the FAQ for the time being since
all of my C++ books are at work: http://www.parashift.com/c++-faq-lit....html#faq-34.3
Phlip wrote: AnonMail2005 wrote:
Vector is the way to go.
I have read in Meyers that &v[0] is not advisable unless v.size () > 0.
To the intermediates:
Bow before /C++ Coding Standards : 101 Rules, Guidelines, and Best Practices/ (C++ in Depth Series) by Herb Sutter & Andrei Alexandrescu. It covers such scratchy situations as interfacing to a C API that likes raw pointers.
They advise the &v[0] trick, and I can't recall if they warn about the size() == 0 situation.
Now I thought that all containers always have a valid .begin() and .end(), and if they equal then the container is empty, so this might suggest that &v[0] is always valid (whereas v[0] is not, because it dereferences an unconstructed object).
So where am I wrong?
To the newbies:
The original poster appeared to be writing their own function that takes a pointer. If so, they should avoid pointers (as should coders at all levels), and should pass a reference to a vector:
typedef std::vector<int> ints_type; void foo(ints_type & ints);
References have fewer features, so they are always better than pointers, and vectors have more features than arrays, so they are always better than arrays.
Always pick the technique with fewer features. Or more features. I'll try again.
Always pick the technique with the safest features. Raw pointers have many unsafe features, and vectors have many safe ones.
-- Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
AnonMail2005 wrote: v.begin () and v.end (), of course are valid. But you can't dereference (i.e. access) v.end (). And since v.begin () == v.end () for an empty vector, why would you think you could derefernce v.begin () for an empty vector?
Try this:
assert(0 < v.size() || v.end() == v.begin()); // well defined?
assert(&v[0] == &*v.end()); // not always well defined?
assert(0 < v.size() || &v[v.size()] == v.end()); // always well defined?
So for an empty vector, v.end() == v.begin(), while v[0] is invalid because
v.end() is simply magic - there's no secret contained sequence that it's off
the end of.
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
The crux of the matter is when it is ok to _dereference_ an iterator.
Your first statement is just iterator comparison - they aren't
dereferenced - so it is safe.
It is not ok to dereference v.end () so *v.end () is not ok. Even if
you do this &*v.end(), so your second statement is not safe.
v[N] where N is an integer is _dereferencing_. So your third statement
is not safe. And neither is v[0] for an empty vector for same reason
as why it is not safe to dereference v.end ().
Phlip wrote: AnonMail2005 wrote:
v.begin () and v.end (), of course are valid. But you can't dereference (i.e. access) v.end (). And since v.begin () == v.end () for an empty vector, why would you think you could derefernce v.begin () for an empty vector?
Try this:
assert(0 < v.size() || v.end() == v.begin()); // well defined?
assert(&v[0] == &*v.end()); // not always well defined?
assert(0 < v.size() || &v[v.size()] == v.end()); // always well defined?
So for an empty vector, v.end() == v.begin(), while v[0] is invalid because v.end() is simply magic - there's no secret contained sequence that it's off the end of.
-- Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
I should have added that your first statement never needs the size
check.
And your third statement is never safe even with the size check. An**********@gmail.com wrote: The crux of the matter is when it is ok to _dereference_ an iterator.
Your first statement is just iterator comparison - they aren't dereferenced - so it is safe.
It is not ok to dereference v.end () so *v.end () is not ok. Even if you do this &*v.end(), so your second statement is not safe.
v[N] where N is an integer is _dereferencing_. So your third statement is not safe. And neither is v[0] for an empty vector for same reason as why it is not safe to dereference v.end ().
Phlip wrote: AnonMail2005 wrote:
v.begin () and v.end (), of course are valid. But you can't dereference (i.e. access) v.end (). And since v.begin () == v.end () for an empty vector, why would you think you could derefernce v.begin () for an empty vector?
Try this:
assert(0 < v.size() || v.end() == v.begin()); // well defined?
assert(&v[0] == &*v.end()); // not always well defined?
assert(0 < v.size() || &v[v.size()] == v.end()); // always well defined?
So for an empty vector, v.end() == v.begin(), while v[0] is invalid because v.end() is simply magic - there's no secret contained sequence that it's off the end of.
-- Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Phlip posted: Tomás wrote:
delete [] reinterpret_cast< char * > ( &str );
More than enough rope to shoot your foot off, huh? ;-)
Actually I could've just written:
delete [] &str[0];
If you define an array as follows:
char array[70];
Then the following expressions all have unique types:
1: array
Type: char[70]
2: &array
Type: char[70] *
3: array[0]
Type: char
4: &array[0]
Type: char *
( I haven't taken modifiers into account, e.g. "const" )
Beginners tend not to see the distinction because 1, 2 and 4 can all
implicity convert to: char *.
If we define an array of char's with "new", e.g.:
new char[5]
The type of the above expression is not: char[5] *
But rather: char *
Therefore, when calling "delete", it makes sense to give it an expression of
type: char *
rather than: char[5] *
which is why I employed "reinterpret_cast" in my initial post.
Anyway, you could always give the people nice pretty functions:
#include <cstddef>
#include <iostream>
using std::cout;
using std::endl;
template<class T>
class TypeSheath
{
public:
typedef T Actual;
typedef T& Ref;
typedef T* Ptr;
typedef const T* ConstPtr;
};
template<class T, std::size_t i>
T (& NewArray())[i]
{
return * reinterpret_cast< T (*)[i] > ( new T[i] );
}
template<class T, std::size_t i>
void DeleteArray( T (&array)[i] )
{
delete [] &array[0];
}
int main()
{
char (&str1)[15] = NewArray<char,15>();
//Or, if you'd prefer:
TypeSheath<char[15]>::Ref str2 = NewArray<char,15>();
str1[0] = 'H';
str1[1] = 'e';
str1[2] = 'l';
str1[3] = 'l';
str1[4] = 'o';
str1[5] = '\n';
str1[6] = 0;
str2[0] = 'H';
str2[1] = 'e';
str2[2] = 'l';
str2[3] = 'l';
str2[4] = 'o';
str2[5] = '\n';
str2[6] = 0;
cout << str1 << str2;
DeleteArray(str1);
DeleteArray(str2);
}
-Tomás An**********@gmail.com wrote: An**********@gmail.com wrote: Phlip wrote: AnonMail2005 wrote:
v.begin () and v.end (), of course are valid. But you can't dereference (i.e. access) v.end (). And since v.begin () == v.end () for an empty vector, why would you think you could derefernce v.begin () for an empty vector? Try this:
assert(0 < v.size() || v.end() == v.begin()); // well defined?
assert(&v[0] == &*v.end()); // not always well defined?
assert(0 < v.size() || &v[v.size()] == v.end()); // always well defined?
So for an empty vector, v.end() == v.begin(), while v[0] is invalid because v.end() is simply magic - there's no secret contained sequence that it's off the end of. The crux of the matter is when it is ok to _dereference_ an iterator.
Your first statement is just iterator comparison - they aren't dereferenced - so it is safe.
It is not ok to dereference v.end () so *v.end () is not ok. Even if you do this &*v.end(), so your second statement is not safe.
v[N] where N is an integer is _dereferencing_. So your third statement is not safe. And neither is v[0] for an empty vector for same reason as why it is not safe to dereference v.end (). I should have added that your first statement never needs the size check.
And your third statement is never safe even with the size check.
Please, do not top-post.
As I understand it, it is safe to have a _pointer_ to an element one
past the end of an array. Isn't it safe to have a _reference_ to the same?
If it is, then &v[0] should be ok, since vector's subscript operator
returns a reference.
Martin
Tomás wrote: If you define an array as follows:
char array[70];
Then the following expressions all have unique types:
1: array Type: char[70]
2: &array Type: char[70] *
The actual type is 'char (*)[70]'. 3: array[0] Type: char
4: &array[0] Type: char *
( I haven't taken modifiers into account, e.g. "const" )
Beginners tend not to see the distinction because 1, 2 and 4 can all implicity convert to: char *.
'char (*)[70]' can most certainly not. If we define an array of char's with "new", e.g.:
new char[5]
The type of the above expression is not: char[5] *
But rather: char *
Therefore, when calling "delete", it makes sense to give it an expression of type: char *
rather than: char[5] *
which is why I employed "reinterpret_cast" in my initial post.
You're very lucky it worked.
Btw: do you think that the following assumption always holds?
assert(sizeof(char (*)[70]) == sizeof(char *)); [snip] An**********@gmail.com wrote: Vector is the way to go.
I have read in Meyers that &v[0] is not advisable unless v.size () > 0.
The *only* correct way is to use v.data(). Unfortunately, the 1998
standard wording was too general to allow funky implementations of
vector so the contiguous element guarantee wasn't there and neither was
the data function: http://www.open-std.org/JTC1/SC22/WG...efects.html#69 http://www.open-std.org/JTC1/SC22/WG...fects.html#464
C++TC1 in 2003 fixed the contiguous issue and (I believe) TC2 will fix
the data issue. But that's not really helpful today so I'd suggest
either:
- edit your stl headers to include the data member (if your vendor
didn't do that already)
- write a global function data() that does &v[0] and use that
everywhere until vector::data is reasonably implemented
- use this expression v.empty() ? 0 : &v[0] (or do this in your global
data function if you really want to play it slow but safe).
But as a warning. On many vector implementations, if you haven't
inserted any elements yet, v.data() returns null. As stupid as it may
sound, some functions cannot take null pointers even if you pass it a
size of 0 (most functions in standard C are undefined if you do this).
BTW your Xnews is not setting your encoding properly; the a in your name
comes up different on different newsreaders.
Tomas wrote: delete [] reinterpret_cast< char * > ( &str ); More than enough rope to shoot your foot off, huh? ;-)
Actually I could've just written:
Understand I didn't read the prior posts. I was just responding to the sight
of
- reinterpret_cast
- &
- delete
- char *
- and []
all in one line!
You are correct to wrap scary-looking things up (if you _must_ use them)
into smart typesafe wrappers.
DeleteArray(str1);
The next step here is either to put that into a destructor, so it follows
Resource Acquisition Is Initialization...
....or to refactor the code to not need all those clever-clever things.
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Martin Vejnar wrote: Please, do not top-post.
+1
As I understand it, it is safe to have a _pointer_ to an element one past the end of an array. Isn't it safe to have a _reference_ to the same?
Yes, but...
If it is, then &v[0] should be ok, since vector's subscript operator returns a reference.
I suspect we have learned that when .size() == 0, .end() might be magic, not
one-off-the-end, so there might be no 0-length controlled array to
So is this well-formed and well-defined?
int * p = new int[0];
assert(p == &p[0]);
delete[] p;
(And note that I decline to consider assert(false) as "well-defined". Abrupt
program termination without calling many destructors sounds very close to
undefined to me...)
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Phlip wrote: Martin Vejnar wrote:
Please, do not top-post. +1
I don't understand what that means. As I understand it, it is safe to have a _pointer_ to an element one past the end of an array. Isn't it safe to have a _reference_ to the same? Yes, but...
If it is, then &v[0] should be ok, since vector's subscript operator returns a reference.
I suspect we have learned that when .size() == 0, .end() might be magic, not one-off-the-end, so there might be no 0-length controlled array to
True enough, see below. So is this well-formed and well-defined?
int * p = new int[0]; assert(p == &p[0]); delete[] p;
(And note that I decline to consider assert(false) as "well-defined". Abrupt program termination without calling many destructors sounds very close to undefined to me...)
Yes, it is.
Regarding the first line:
[5.3.4/7] When the value of the expression in a direct-new-declarator is
zero, the allocation function is called to allocate an array
with no elements.
So we have a valid pointer to an array. Regarding the second line, we
can modify '&p[0]' like this:
&p[0] === &(p[0]) === &(*(p+0)) == &(*p) === &*p
Up until now, everything is well-defined.
The question that arises is whether '&*p == p' for 'p' pointing to an
element one past the end of array. I couldn't find any relevant clause
(which doesn't mean that there isn't any, it merely shows my inability
to search. If you know where such a clause is, feel free to enlighten
me) in the Standard that would support my opinion, but AFAIK we're
allowed to refer to one element past the end of array, as long as we
don't try to access the value stored in that element.
Since we're not accessing the value (the * operator returns an lvalue,
the & operator accepts an lvalue, thus no lvalue-to-rvalue conversion
takes place), I believe that we are allowed to say '&*p == p'.
The problem with vector's [] operator is quite different. As I was
thinking about it, I realized, that my assuptions were wrong. '&v[n]',
where 'v.size() == n' is indeed undefined, as we do not know what really
happens inside operator []. (Unlike your int * example, where 'a[b]' is
defined to be equivalent to '*(a+b)'.) The Standard only defines its
behavior for '0 <= n < size()'.
Martin
Martin Vejnar wrote: Please, do not top-post.
+1
I don't understand what that means.
It means one vote in favor of the statement.
(And note that I decline to consider assert(false) as "well-defined". Abrupt program termination without calling many destructors sounds very close to undefined to me...)
Yes, it is.
So is assert(false); itself undefined? Is this undefined?
#include <assert.h>
int main() { assert(false); }
Up until now, everything is well-defined.
The question that arises is whether '&*p == p' for 'p' pointing to an element one past the end of array. I couldn't find any relevant clause (which doesn't mean that there isn't any, it merely shows my inability to search. If you know where such a clause is, feel free to enlighten me) in the Standard that would support my opinion, but AFAIK we're allowed to refer to one element past the end of array, as long as we don't try to access the value stored in that element.
If you can't find it, I certainly won't be able to!
Since we're not accessing the value (the * operator returns an lvalue, the & operator accepts an lvalue, thus no lvalue-to-rvalue conversion takes place), I believe that we are allowed to say '&*p == p'.
That sounds good enough!
The problem with vector's [] operator is quite different. As I was thinking about it, I realized, that my assuptions were wrong. '&v[n]', where 'v.size() == n' is indeed undefined, as we do not know what really happens inside operator []. (Unlike your int * example, where 'a[b]' is defined to be equivalent to '*(a+b)'.) The Standard only defines its behavior for '0 <= n < size()'.
Ah, so v[n] doesn't follow the same off-the-end rules as raw vectors or
iterators.
In summary: Write stupid code that obviously works, and use v.size() > 0 to
defend &v[0].
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Phlip wrote: Martin Vejnar wrote:
Please, do not top-post. +1 I don't understand what that means.
It means one vote in favor of the statement. (And note that I decline to consider assert(false) as "well-defined". Abrupt program termination without calling many destructors sounds very close to undefined to me...)
Yes, it is.
So is assert(false); itself undefined? Is this undefined?
#include <assert.h> int main() { assert(false); }
Up until now, everything is well-defined.
The question that arises is whether '&*p == p' for 'p' pointing to an element one past the end of array. I couldn't find any relevant clause (which doesn't mean that there isn't any, it merely shows my inability to search. If you know where such a clause is, feel free to enlighten me) in the Standard that would support my opinion, but AFAIK we're allowed to refer to one element past the end of array, as long as we don't try to access the value stored in that element.
If you can't find it, I certainly won't be able to!
Since we're not accessing the value (the * operator returns an lvalue, the & operator accepts an lvalue, thus no lvalue-to-rvalue conversion takes place), I believe that we are allowed to say '&*p == p'.
That sounds good enough!
The problem with vector's [] operator is quite different. As I was thinking about it, I realized, that my assuptions were wrong. '&v[n]', where 'v.size() == n' is indeed undefined, as we do not know what really happens inside operator []. (Unlike your int * example, where 'a[b]' is defined to be equivalent to '*(a+b)'.) The Standard only defines its behavior for '0 <= n < size()'.
Ah, so v[n] doesn't follow the same off-the-end rules as raw vectors or iterators.
In summary: Write stupid code that obviously works, and use v.size() > 0 to defend &v[0].
-- Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
After consulting with my books I can tell you that Meyers' Effective
STL says to guard against doing &v[0] when size () == 0.
The Sutter/Alexandrescu book C++ Coding Standards does not mention this
but they cite the Meyers book as a relevant reference for this item.
And, the FAQ agrees with Meyers. The actual type is 'char (*)[70]'.
My bad. ..can all implicity convert to: char *.
'char (*)[70]' can most certainly not.
*goes off and tries to compile it...*
Woops, you're right.
Btw: do you think that the following assumption always holds?
assert(sizeof(char (*)[70]) == sizeof(char *));
Aren't all pointers the same? Same alignment, same amount of bits.
We can use "void*" to store any sort of pointer... so it would make sense
if all pointer variables were the same.
-Tomás
Tomás wrote: Aren't all pointers the same? Same alignment, same amount of bits.
No.
We can use "void*" to store any sort of pointer... so it would make sense if all pointer variables were the same.
A void* is large enough to store any pointer that can be implicitly
converted to void*.
Pointers to members are completely separate from void*.
Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Ben Pope wrote: Pointers to members are completely separate from void*.
Pointers to members differ so completely from pointers that they should not
be called "pointers". They should be called "smart offsets", or
"discriminants". Smart because they know if the target is virtual, offsets
because they know where in an object the target is, and discriminants
because they bind typesafely.
A pointer to member cannot be typecast.
--
Phlip http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
In article <ut******************@news.indigo.ie>, NU**@NULL.NULL says...
[ ... ] Aren't all pointers the same? Same alignment, same amount of bits.
Not necessarily. Just for one example, on a Cray a normal
address is of a 64-bit word. C and C++ use 8 bits for
char and 64 bits for everything else. A pointer to
anything else is basically a raw address, but a pointer
to char is an address _plus_ 3 extra bits to specify a
byte inside of that word.
We can use "void*" to store any sort of pointer... so it would make sense if all pointer variables were the same.
It's also guaranteed that void * and char * have the same
representation -- but that's about it. An int * can be
(and as mentioned above, on at least one type of machine,
is) different.
--
Later,
Jerry.
The universe is a figment of its own imagination. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Metzen |
last post by:
hello,
ok, I want to find the length of an int array that is being passed to a function:
main()
{
int array={1,2,3,4,5,6,7,8};
function(array);
}
function(int *array)
{
|
by: Xiangliang Meng |
last post by:
Hi, all.
What will we get from sizeof(a class without data members and virtual
functions)?
For example:
class abnormity {
public:
string name() { return "abnormity"; }
|
by: nzanella |
last post by:
Hello,
I just thought I would share the following observation with the rest
of the group. The sizeof operator seems to act differently according
to whether the number of elements in the array is...
|
by: fdunne2 |
last post by:
The following C-code implements a simple FIR filter:
//realtime filter demo
#include <stdio.h>
#include <stdlib.h>
//function defination
float rtFilter1(float *num, float *den, float...
|
by: ak |
last post by:
struct xy{
int x;
int y;
}
_xy;
size_of_xy(struct xy * a) {
int len = sizeof a;
printf( "\sizeof xy: %i\n", len );
}
|
by: junky_fellow |
last post by:
Consider the following piece of code:
#include <stddef.h>
int main (void)
{
int i, j=1;
char c;
printf("\nsize =%lu\n", sizeof(i+j));
|
by: valerio |
last post by:
Hello all
I would like to dinamically allocate an array of array of structures.
To explain this:
struct file{ char* fileName,int inode) myfiles;
struct file{ char* fileName,int inode) mydirs;
...
|
by: Nishu |
last post by:
Hi All,
When I run the below program in MSVC, I get the output as
1
4
Could you tell me why sizeof 'A' is taken as 4? Is it standard defined
or compiler specific?
Thanks,
Nishu...
|
by: c.lang.myself |
last post by:
whenever we pass an array to function, we have to also pass its
size.e.g if i am making a soritng function then
void sort(int b,int size);
Now I thought about using sizeof operator(macro?)...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM)
Please note that the UK and Europe revert to winter time on...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
|
by: isladogs |
last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, Mike...
| |