copying Vector elements into Dynamic Array

A

arnuld

/* 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<int> ivec;

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 ?
 
A

Alf P. Steinbach

* arnuld:
/* 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<int> ivec;

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 ?

No, the last element has an indeterminate value (which just might be 0).

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.
 
A

arnuld

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)

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 ?
 
A

Alf P. Steinbach

* arnuld:
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)

Right. You don't need more elements than you need.

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:

"C-style array" is a very imprecise made-up term which doesn't really
mean anything specific except that it should be possible to do in C.

String literals are zero-terminated.

Other arrays need not be zero-terminated, and if the element type does
not have a zero value then it's impossible to have the array
zero-terminated.
 
G

Guest

/* 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<int> ivec;

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 = ivec;
}

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.
 
B

Bo Persson

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 = ivec;
:: }
::
:: 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
 
A

arnuld

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 ?
 
A

arnuld

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 ;-)
 
A

arnuld

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 = ivec;
}
}
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)
 
J

James Kanze

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::eek:stream_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).
 
G

Guest

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::eek:stream_iterator< int >( std::cout, "\n" ) ) ;
 
G

Guest

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 = ivec;
}
}
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).
 
V

Victor Bazarov

Erik said:
[..]
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
 
A

arnuld

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 $
 
A

arnuld

std::copy( pdarr, pdarr + ivec.size(),
std::eek:stream_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
 
J

Jerry Coffin

[ ... ]
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.
 
V

Victor Bazarov

Jerry said:
[ ... ]
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
 
J

James Kanze

Erik said:
[..]
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.
 
J

James Kanze

Jerry said:
[ ... ]
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?)
 
J

Jerry Coffin

Jerry said:
[ ... ]
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top