By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,512 Members | 3,790 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,512 IT Pros & Developers. It's quick & easy.

copying Vector elements into Dynamic Array

P: n/a
/* C++ Primer - 4/e

* chapter 4- Arrays & Pointers, exercise 4.28
* STATEMENT
* write a programme to read the standard input and build a vector
of integers from values that are read. allocate an array of the same
size as the vector and copy elements from the vector into the array

*/

#include <iostream>
#include <vector>

int main()
{
int iv;
std::vector<intivec;

while(std::cin >iv)
{
ivec.push_back(iv);
}

const size_t arr_sz = ivec.size() + 1;
int* pdarr = new int[arr_sz];
int* pbegin = pdarr;
/* we will use "pbegin" to print the array elements later */

/* assign elements from vector to the dynamic array */
for(std::vector<int>::const_iterator iter=ivec.begin();
iter != ivec.end(); ++iter)
{
*pdarr++ = *iter;
}
/* printing the elements of arrar */
std::cout << "printing array elements: ";
for(int* q = pbegin; q != pbegin + arr_sz; ++q)
{
std::cout << *q << " ";
}

std::cout << std::endl;

return 0;
}

======== OUTPUT ===========
~/programming/cpp $ g++ -ansi -pedantic -Wall -Wextra ex_04-28.cpp
~/programming/cpp $ ./a.out
2
3
-9
8
printing array elements: 2 3 -9 8 0
~/programming/cpp $
i have 2 questions:

1.) i have used "vecotor size + 1" for array size but i did not enter last
character as NULL. does the programme add it to the end of array itself
automatically ?

2.) output contains an extra integer in the end, the zero, 0. i am not
letting the pointer slipping-off the end of array because i used "q !=
pbegin + arr_size" then from where the zero came ?
--
-- http://arnuld.blogspot.com

Jul 24 '07 #1
Share this Question
Share on Google+
19 Replies


P: n/a
On Tue, 24 Jul 2007 08:37:34 +0200, Alf P. Steinbach wrote:
>* arnuld:
i have 2 questions:

1.) i have used "vecotor size + 1" for array size but i did not enter last
character as NULL. does the programme add it to the end of array itself
automatically ?
No, the last element has an indeterminate value (which just might be 0).
it means there is no harm in choosing the size of C++ dynamic array as
equal as the vector. (i am not talking about C-style array at this
point)

>2.) output contains an extra integer in the end, the zero, 0. i am not
letting the pointer slipping-off the end of array because i used "q !=
pbegin + arr_size" then from where the zero came ?
It's the last element of the array. You chose an array size 1 larger
than the vector size.
if i want to make sure that that i have a C-style array .i.e. having a
NULL character in the end then i can use this:

/* assign elements from vector to the dynamic array */
for(std::vector<int>::const_iterator iter=ivec.begin();
iter != ivec.end(); ++iter)
{
*pdarr++ = *iter;
}

*pdarr = '\0';

but i still get the same output. why now ?
--
-- http://arnuld.blogspot.com

Jul 24 '07 #2

P: n/a
On 2007-07-24 08:26, arnuld wrote:
/* C++ Primer - 4/e

* chapter 4- Arrays & Pointers, exercise 4.28
* STATEMENT
* write a programme to read the standard input and build a vector
of integers from values that are read. allocate an array of the same
size as the vector and copy elements from the vector into the array

*/

#include <iostream>
#include <vector>

int main()
{
int iv;
std::vector<intivec;

while(std::cin >iv)
{
ivec.push_back(iv);
}

const size_t arr_sz = ivec.size() + 1;
No need to add one extra, see below.
int* pdarr = new int[arr_sz];
int* pbegin = pdarr;
/* we will use "pbegin" to print the array elements later */

/* assign elements from vector to the dynamic array */
for(std::vector<int>::const_iterator iter=ivec.begin();
iter != ivec.end(); ++iter)
{
*pdarr++ = *iter;
}
Often when iterating through vectors I find that the index of the index
of the current element is of interest for more purposes than indexing
into the vector, and in these cases I tend to not use iterators:

for (size_t i = 0; i < ivec.size(); ++i)
{
pdarr[i] = ivec[i];
}

this way you get slightly cleaner code, and you don't need the two
pointers to the array.
/* printing the elements of arrar */
std::cout << "printing array elements: ";
for(int* q = pbegin; q != pbegin + arr_sz; ++q)
{
std::cout << *q << " ";
}
One again, I'd probably use indexing. It puts more emphasis on the fact
that I'm going through an array and hides the fact that I'm playing with
pointers.
std::cout << std::endl;

return 0;
}
You forgot to free the array.
======== OUTPUT ===========
~/programming/cpp $ g++ -ansi -pedantic -Wall -Wextra ex_04-28.cpp
~/programming/cpp $ ./a.out
2
3
-9
8
printing array elements: 2 3 -9 8 0
~/programming/cpp $
i have 2 questions:

1.) i have used "vecotor size + 1" for array size but i did not enter last
character as NULL. does the programme add it to the end of array itself
automatically ?

2.) output contains an extra integer in the end, the zero, 0. i am not
letting the pointer slipping-off the end of array because i used "q !=
pbegin + arr_size" then from where the zero came ?
You seem to be confusing things, C-style arrays are not 0-terminated, if
that was the case how would you tell the difference between an element
in the middle of an int-array that was 0 and the end? You are thinking
of C-style strings, which are 0-terminated char-arrays.

--
Erik Wikström
Jul 24 '07 #3

P: n/a
Erik Wikström wrote:
:: On 2007-07-24 08:26, arnuld wrote:
::
::: int* pdarr = new int[arr_sz];
::: int* pbegin = pdarr;
::: /* we will use "pbegin" to print the array elements later */
:::
::: /* assign elements from vector to the dynamic array */
::: for(std::vector<int>::const_iterator iter=ivec.begin();
::: iter != ivec.end(); ++iter)
::: {
::: *pdarr++ = *iter;
::: }
::
:: Often when iterating through vectors I find that the index of the
:: index of the current element is of interest for more purposes than
:: indexing into the vector, and in these cases I tend to not use
:: iterators:
::
:: for (size_t i = 0; i < ivec.size(); ++i)
:: {
:: pdarr[i] = ivec[i];
:: }
::
:: this way you get slightly cleaner code, and you don't need the two
:: pointers to the array.

Even cleaner code would be

std::copy(ivec.begin(), ivec.end(), pdarr);

Let the standard library decide how to do a copy properly.
::
::: ======== OUTPUT ===========
::: ~/programming/cpp $ g++ -ansi -pedantic -Wall -Wextra ex_04-28.cpp
::: ~/programming/cpp $ ./a.out
::: 2
::: 3
::: -9
::: 8
::: printing array elements: 2 3 -9 8 0
::: ~/programming/cpp $
:::
:::
::: i have 2 questions:
:::
::: 1.) i have used "vecotor size + 1" for array size but i did not
::: enter last character as NULL. does the programme add it to the
::: end of array itself automatically ?
:::
::: 2.) output contains an extra integer in the end, the zero, 0. i
::: am not letting the pointer slipping-off the end of array because
::: i used "q != pbegin + arr_size" then from where the zero came ?
::
:: You seem to be confusing things, C-style arrays are not
:: 0-terminated, if that was the case how would you tell the
:: difference between an element in the middle of an int-array that
:: was 0 and the end? You are thinking of C-style strings, which are
:: 0-terminated char-arrays.

This is the curse of starting with the C subset of C++. Now you
(arnuld) have learned something that only applies to a very special
case -- using an array of char to simulate a string.

Time to start unlearning! :-)
Bo Persson
Jul 24 '07 #4

P: n/a
On Tue, 24 Jul 2007 12:51:12 +0200, Bo Persson wrote:
Even cleaner code would be
std::copy(ivec.begin(), ivec.end(), pdarr);

Let the standard library decide how to do a copy properly.
WOW man, it works .... what can be the code for printing
the elements of that array to std::cout ?


--
-- http://arnuld.blogspot.com

Jul 24 '07 #5

P: n/a
On Tue, 24 Jul 2007 12:51:12 +0200, Bo Persson wrote:
Even cleaner code would be

std::copy(ivec.begin(), ivec.end(), pdarr);

Let the standard library decide how to do a copy properly.
i forgot to mention the one nice point: it does not modify the pointer,
pdarr, so i do not need an extra pointer :)

... what a KISS ..
This is the curse of starting with the C subset of C++. Now you (arnuld)
have learned something that only applies to a very special case -- using
an array of char to simulate a string.
Time to start unlearning! :-)
OK, will start with you ;-)

--
-- http://arnuld.blogspot.com

Jul 24 '07 #6

P: n/a
On Tue, 24 Jul 2007 08:36:19 +0000, Erik Wikström wrote:
Often when iterating through vectors I find that the index of the index
of the current element is of interest for more purposes than indexing
into the vector, and in these cases I tend to not use iterators:

for (size_t i = 0; i < ivec.size(); ++i) {
pdarr[i] = ivec[i];
}
}
this way you get slightly cleaner code, and you don't need the two
pointers to the array.
i do not use indexing because i am quite poor when it comes to the
undertanding of pointers and iterators. so i keep on using
iterators/pointers to understand how they work

You forgot to free the array.
ouch!

You seem to be confusing things, C-style arrays are not 0-terminated, if
that was the case how would you tell the difference between an element
in the middle of an int-array that was 0 and the end? You are thinking
of C-style strings, which are 0-terminated char-arrays.
OK, now i got it. character-arrays (not arrays) are NULL terminated in
C. ut why you call it "0-terminated" ? (it is "\0-terminated" which is
diferent from the zero)
--
-- http://arnuld.blogspot.com

Jul 24 '07 #7

P: n/a
On Jul 24, 1:39 pm, arnuld <geek.arn...@gmail.comwrote:
On Tue, 24 Jul 2007 12:51:12 +0200, Bo Persson wrote:
Even cleaner code would be
std::copy(ivec.begin(), ivec.end(), pdarr);
Let the standard library decide how to do a copy properly.
WOW man, it works .... what can be the code for printing
the elements of that array to std::cout ?
There is an ostream_iterator, which would allow:

std::copy( v.begin(), v.end(),
std::ostream_iterator< int >( std::cout, "\n" ) ) ;

In practice, it's not very useful, because you usually need to
handle additional formatting chores: only 10 to a line,
separator, rather than terminator, etc. Which means you end up
with something like:

int inLineCount = 0 ;
for ( std::vector< int >::const_iterator it = v.begin() ;
it != v.end() ;
++ it ) {
if ( inLineCount == 0 ) {
std::cout << lineHeader ;
} else {
std::cout << inlineSeparator ;
}
std::cout << *it ;
++ inLineCount ;
if ( inLineCount == maxInLine ) {
std::cout << completeLineTermiator ;
inLineCount = 0 ;
}
}
if ( inLineCount != 0 ) {
std::cout << partialLineTerminator ;
}

If you want to use something like a comma separator, attached to
the preceding element, then you'll also need logic to handle
that (something that checks whether (it + 1) == v.end() in the
loop).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 24 '07 #8

P: n/a
On 2007-07-24 13:39, arnuld wrote:
>On Tue, 24 Jul 2007 12:51:12 +0200, Bo Persson wrote:
Even cleaner code would be
>std::copy(ivec.begin(), ivec.end(), pdarr);

Let the standard library decide how to do a copy properly.

WOW man, it works .... what can be the code for printing
the elements of that array to std::cout ?
std::copy( pdarr, pdarr + ivec.size(),
std::ostream_iterator< int >( std::cout, "\n" ) ) ;

--
Erik Wikström
Jul 24 '07 #9

P: n/a
On 2007-07-24 13:56, arnuld wrote:
>On Tue, 24 Jul 2007 08:36:19 +0000, Erik Wikström wrote:
Often when iterating through vectors I find that the index of the index
of the current element is of interest for more purposes than indexing
into the vector, and in these cases I tend to not use iterators:

for (size_t i = 0; i < ivec.size(); ++i) {
pdarr[i] = ivec[i];
}
}
this way you get slightly cleaner code, and you don't need the two
pointers to the array.

i do not use indexing because i am quite poor when it comes to the
undertanding of pointers and iterators. so i keep on using
iterators/pointers to understand how they work

>You forgot to free the array.

ouch!

>You seem to be confusing things, C-style arrays are not 0-terminated, if
that was the case how would you tell the difference between an element
in the middle of an int-array that was 0 and the end? You are thinking
of C-style strings, which are 0-terminated char-arrays.

OK, now i got it. character-arrays (not arrays) are NULL terminated in
C. ut why you call it "0-terminated" ? (it is "\0-terminated" which is
diferent from the zero)
Because in ASCII the null-character (\0) has the value 0x0, or to put it
in code:

static_cast<int>('\0') == 0

Notice that the string is not terminated by NULL which is a pointer and
will have a different size than the null-character and its value is not
defined to be 0x0 (though it probably is on most platforms).

--
Erik Wikstöm
Jul 24 '07 #10

P: n/a
Erik Wikström wrote:
[..]
Because in ASCII the null-character (\0) has the value 0x0, or to put
it in code:

static_cast<int>('\0') == 0

Notice that the string is not terminated by NULL which is a pointer
NULL is a macro. It's not a *pointer*. It's something that *can* be
converted into a null pointer value. There is a problem with it, as
you can hopefully verify with your favourite compiler:

#include <iostream>
#include <cstdlib>
void foo(int) {
std::cout << "It's an int\n";
}
void foo(void*) {
std::cout << "It's a pointer\n";
}
int main() {
std::cout << "What is NULL?\n";
foo(NULL);
}

What does it print?
and will have a different size than the null-character and its value
is not defined to be 0x0 (though it probably is on most platforms).
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 24 '07 #11

P: n/a
On Tue, 24 Jul 2007 10:17:59 -0400, Victor Bazarov wrote:
NULL is a macro. It's not a *pointer*. It's something that *can* be
converted into a null pointer value. There is a problem with it, as
you can hopefully verify with your favourite compiler:

#include <iostream>
#include <cstdlib>
void foo(int) {
std::cout << "It's an int\n";
}
void foo(void*) {
std::cout << "It's a pointer\n";
}
int main() {
std::cout << "What is NULL?\n";
foo(NULL);
}

What does it print?
:D

~/programming/cpp $ g++ -ansi -pedantic -Wall -Wextra test.cpp
~/programming/cpp $ ./a.out
What is NULL?
It's an int
~/programming/cpp $
--
-- http://arnuld.blogspot.com

Jul 24 '07 #12

P: n/a
On Tue, 24 Jul 2007 13:49:39 +0000, Erik Wikström wrote:
>On 2007-07-24 13:39, arnuld wrote:
WOW man, it works .... what can be the code for printing
the elements of that array to std::cout ?
std::copy( pdarr, pdarr + ivec.size(),
std::ostream_iterator< int >( std::cout, "\n" ) ) ;
goody-goody ;-)

i just changed the "ivec.size()" to "arr_sz" which was a const i defined
earlier in the programme.

thanks Erik

--
-- http://arnuld.blogspot.com

Jul 24 '07 #13

P: n/a
In article <pa****************************@gmail.com>,
ge*********@gmail.com says...

[ ... ]
What is NULL?
It's an int
Note that this is a (potential) difference between C and C++: in C++,
NULL is _always_ an int. In C, it can be either an int or a pointer to
void.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 24 '07 #14

P: n/a
Jerry Coffin wrote:
In article <pa****************************@gmail.com>,
ge*********@gmail.com says...

[ ... ]
>What is NULL?
It's an int

Note that this is a (potential) difference between C and C++: in C++,
NULL is _always_ an int. In C, it can be either an int or a pointer to
void.
I think the actual difference is that in C conversion from 'void*'
to any pointer type is implicit, whereas in C++ it isn't.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 24 '07 #15

P: n/a
On Jul 24, 4:17 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Erik Wikström wrote:
[..]
Because in ASCII the null-character (\0) has the value 0x0, or to put
it in code:
static_cast<int>('\0') == 0
Notice that the string is not terminated by NULL which is a pointer
NULL is a macro. It's not a *pointer*. It's something that *can* be
converted into a null pointer value. There is a problem with it, as
you can hopefully verify with your favourite compiler:
#include <iostream>
#include <cstdlib>
void foo(int) {
std::cout << "It's an int\n";
}
void foo(void*) {
std::cout << "It's a pointer\n";
}
int main() {
std::cout << "What is NULL?\n";
foo(NULL);
}
Of course, that will generate a warning from the compiler.
What does it print?
I'm tempted to say: who cares? If it makes a difference, you
shouldn't be overloading the functions in the first place.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 24 '07 #16

P: n/a
On Jul 24, 6:17 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Jerry Coffin wrote:
In article <pan.2007.07.24.15.13.04.976...@gmail.com>,
geek.arn...@gmail.com says...
[ ... ]
What is NULL?
It's an int
Note that this is a (potential) difference between C and C++: in C++,
NULL is _always_ an int. In C, it can be either an int or a pointer to
void.
I think the actual difference is that in C conversion from 'void*'
to any pointer type is implicit, whereas in C++ it isn't.
That's also a difference, but C very definitly says that an
integral constant expression evaluating to 0, OR the same,
explicitly cast to void*, is a null pointer constant. (Don't
ask my why?)

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 24 '07 #17

P: n/a
In article <f8**********@news.datemas.de>, v.********@comAcast.net
says...
Jerry Coffin wrote:
In article <pa****************************@gmail.com>,
ge*********@gmail.com says...

[ ... ]
What is NULL?
It's an int
Note that this is a (potential) difference between C and C++: in C++,
NULL is _always_ an int. In C, it can be either an int or a pointer to
void.

I think the actual difference is that in C conversion from 'void*'
to any pointer type is implicit, whereas in C++ it isn't.
That's certainly a difference as well -- and arguably a more important
one. The C standard, however, is quite explicit in saying that NULL is
an implementation defined null pointer constant. A null pointer constant
is, in turn, defined as (6.3.2.3/3): "An integer constant expression
with the value 0, or such an expression cast to type void * [...]"

The reason I say the implicit conversion is arguably more important is
because it's what makes it reasonable to define NULL as a pointer to
void rather than an int. IOW, the one is more or less a consequence of
the other.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 25 '07 #18

P: n/a
On Jul 25, 4:25 am, Jerry Coffin <jcof...@taeus.comwrote:

[...]
The reason I say the implicit conversion is arguably more important is
because it's what makes it reasonable to define NULL as a pointer to
void rather than an int. IOW, the one is more or less a consequence of
the other.
Reread that, and please explain why it is more reasonable to
define a "null POINTER constant" as an int than as a pointer
(regardless of type). Implicit conversion (other than the null
pointer conversion) are irrelevant, because we're talking about
a special case, where compiler magic is involved.

The only thing one can really conclude is that none of this is
reasonable, and that we really need a real null pointer type
(for which there is a proposal, so we might actually get it in
the next version of the standard).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 25 '07 #19

P: n/a
In article <11*********************@r34g2000hsd.googlegroups. com>,
ja*********@gmail.com says...
On Jul 25, 4:25 am, Jerry Coffin <jcof...@taeus.comwrote:

[...]
The reason I say the implicit conversion is arguably more important is
because it's what makes it reasonable to define NULL as a pointer to
void rather than an int. IOW, the one is more or less a consequence of
the other.

Reread that, and please explain why it is more reasonable to
define a "null POINTER constant" as an int than as a pointer
(regardless of type).
That's not what I meant -- I meant that (in C) you can define NULL as a
pointer to void. In C++, such a definition would be essentially unusable
because you'd have to explicitly cast it every time you mixed it with a
pointer to any other type (i.e. constantly).

[ ... ]
The only thing one can really conclude is that none of this is
reasonable, and that we really need a real null pointer type
(for which there is a proposal, so we might actually get it in
the next version of the standard).
I have no problem with that at all -- quite the contrary, I hope it
makes it into the standard. I think it's a good and useful addition to
the language. The implicit conversion from int to pointer causes quite a
few problems, and while I suppose it can't be eliminated immediately,
adding a usable replacement seems like a good first step toward doing
so.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 25 '07 #20

This discussion thread is closed

Replies have been disabled for this discussion.