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

help about pointer copy

P: n/a
Hi,

I have an array and I want to adjust the size (remove some elements). I use
the following code. Can you help me to check whether it's correct.

////////////// start
int *p1 = new int[oldsize];

// ....
// set the values of p1

int *p2 = p1;
p1 = new int[newsize];

// copy some values from p2 to p1
for ( i = 0; i .... )
if (....) p1[i] = p2[i];

delete []p2;

////////////// end

Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy way
to reset the length of p1? (e.g, p1 becomes int[20] and the first 10
elements keep the original value).

Thank you very much in advance for your help!

JJ
Jul 22 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
"Jinjun Xu" <jj**@ucla.edu> wrote...
I have an array and I want to adjust the size (remove some elements). I use the following code. Can you help me to check whether it's correct.

////////////// start
int *p1 = new int[oldsize];

// ....
// set the values of p1

int *p2 = p1;
p1 = new int[newsize];

// copy some values from p2 to p1
for ( i = 0; i .... )
if (....) p1[i] = p2[i];

delete []p2;

////////////// end
Seems fine.
Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy way to reset the length of p1? (e.g, p1 becomes int[20] and the first 10
elements keep the original value).


You don't have to change anything in that case. Just think you have
fewer elements and only use as many as you think there are. And, no,
there is no "easy way to reset the length" of a dynamic array.

Victor
Jul 22 '05 #2

P: n/a
inline...

"Jinjun Xu" <jj**@ucla.edu> wrote in message
news:c9**********@daisy.noc.ucla.edu...
Hi,

I have an array and I want to adjust the size (remove some elements). I use the following code. Can you help me to check whether it's correct.

////////////// start
int *p1 = new int[oldsize];

// ....
// set the values of p1

int *p2 = p1;
p1 = new int[newsize];

// copy some values from p2 to p1
for ( i = 0; i .... )
if (....) p1[i] = p2[i];

delete []p2;

////////////// end

Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy way to reset the length of p1? (e.g, p1 becomes int[20] and the first 10
elements keep the original value).

Thank you very much in advance for your help!

JJ


The easy way is to use a vector instead of an array. Arrays have a fixed
size limitation while a vector container dynamically resizes itself.
Additionally, all STL containers come equipped with powerful member
functions, iterators and algorithms to swap, sort, replace, append, push,
pop, etc...

as a simple example using a vector of integers and a display function:

#include <iostream>
#include <vector>

void display(std::vector<int>& r_v)
{
std::cout << "vector contents:" << std::endl;

std::vector<int>::iterator it;
for (it = r_v.begin(); it != r_v.end(); it++)
{
std::cout << *it << std::endl;
}
}

int main()
{
std::vector<int> vi;

// add a few elements
vi.push_back(0);
vi.push_back(1);
vi.push_back(2);

std::cout << "vector vi has " << vi.size() << " elements" << std::endl;
display(vi);

// add more elements
vi.push_back(3);
vi.push_back(4);
vi.push_back(5);

std::cout << std::endl << "vector vi has " << vi.size() << " elements"
<< std::endl;
display(vi);

std::cout << std::endl;

return 0;
}

Jul 22 '05 #3

P: n/a
"Jinjun Xu" <jj**@ucla.edu> wrote in message news:<c9**********@daisy.noc.ucla.edu>...
Hi,

I have an array and I want to adjust the size (remove some elements). I use
the following code. Can you help me to check whether it's correct.

////////////// start
int *p1 = new int[oldsize];

// ....
// set the values of p1

int *p2 = p1;
p1 = new int[newsize];

// copy some values from p2 to p1
for ( i = 0; i .... )
if (....) p1[i] = p2[i];

delete []p2;

////////////// end

Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy way
to reset the length of p1? (e.g, p1 becomes int[20] and the first 10
elements keep the original value).

No, there is not a straightforward way to do this with raw pointers.
However you can do what you want using the STL containers std::vector
or std::deque, which will grow automatically as you add data to them.
They also have functions to ensure you have enough space to hold a
minimum number of elements. However, one caveat is that each time
they grow, any pointers (or other iterators) into the container become
invalid.

HTH, Dave Moore
Jul 22 '05 #4

P: n/a

Thank you guys for the reply and help! It was my first post in news group
and I am so happy to get the answer quickly and helpfully.

It seems that I should spend more time on learning using the classes in the
C++ library instead of writing from scratch by myself. My work is on
numerical computation so I need to use vector and matrix often. What I did
is to write the classes CVector and CMatrix by myself. Now I know that
vector class may help me much. Thank you.

JJ

"SaltPeter" <Sa*******@Jupiter.sys> wrote in message
news:hI**********************@news20.bellglobal.co m...
inline...

"Jinjun Xu" <jj**@ucla.edu> wrote in message
news:c9**********@daisy.noc.ucla.edu...
Hi,

I have an array and I want to adjust the size (remove some elements). I use
the following code. Can you help me to check whether it's correct.

////////////// start
int *p1 = new int[oldsize];

// ....
// set the values of p1

int *p2 = p1;
p1 = new int[newsize];

// copy some values from p2 to p1
for ( i = 0; i .... )
if (....) p1[i] = p2[i];

delete []p2;

////////////// end

Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy

way
to reset the length of p1? (e.g, p1 becomes int[20] and the first 10
elements keep the original value).

Thank you very much in advance for your help!

JJ


The easy way is to use a vector instead of an array. Arrays have a fixed
size limitation while a vector container dynamically resizes itself.
Additionally, all STL containers come equipped with powerful member
functions, iterators and algorithms to swap, sort, replace, append, push,
pop, etc...

as a simple example using a vector of integers and a display function:

#include <iostream>
#include <vector>

void display(std::vector<int>& r_v)
{
std::cout << "vector contents:" << std::endl;

std::vector<int>::iterator it;
for (it = r_v.begin(); it != r_v.end(); it++)
{
std::cout << *it << std::endl;
}
}

int main()
{
std::vector<int> vi;

// add a few elements
vi.push_back(0);
vi.push_back(1);
vi.push_back(2);

std::cout << "vector vi has " << vi.size() << " elements" <<

std::endl; display(vi);

// add more elements
vi.push_back(3);
vi.push_back(4);
vi.push_back(5);

std::cout << std::endl << "vector vi has " << vi.size() << " elements"
<< std::endl;
display(vi);

std::cout << std::endl;

return 0;
}

Jul 22 '05 #5

P: n/a
On Thu, 03 Jun 2004 09:31:32 +0200, Dave Moore wrote:
However you can do what you want using the STL containers std::vector or
std::deque, which will grow automatically as you add data to them. They
also have functions to ensure you have enough space to hold a minimum
number of elements. However, one caveat is that each time they grow,
any pointers (or other iterators) into the container become invalid.


Would you elaborate on this a little bit. Does "... become invalid" mean
that the order and offset of the specific elements in the vector could
change and therefor the pointers/iterators become invalid or does it mean
that the order and offset of the vector-elements keep the same when adding
(push_back()) to a vector and just the references become invalid due to
some vector-internal management ?

Thanks in advance for your answer.

Darius.
Jul 22 '05 #6

P: n/a
> It seems that I should spend more time on learning using the classes in
the
C++ library instead of writing from scratch by myself. My work is on
numerical computation so I need to use vector and matrix often. What I did
is to write the classes CVector and CMatrix by myself. Now I know that
vector class may help me much. Thank you.


Try then Newmat library from http://www.robertnz.net/nm_intro.htm

Jul 22 '05 #7

P: n/a
Jinjun Xu posted:
Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy
way to reset the length of p1? (e.g, p1 becomes int[20] and the first
10 elements keep the original value).

Imagine that this is your int[10] in memory:
char double int int int int int int int int int int char double int*
unsigned short int
What I'm getting at is that your int[10] may be boxed-in in memory. Thus,
you're *not guaranteed* that you can make it bigger! You'll have to find an
unused bit of memory of length int[20] and move your values.
-JKop
Jul 22 '05 #8

P: n/a
> On Thu, 03 Jun 2004 09:31:32 +0200, Dave Moore wrote:
However you can do what you want using the STL containers std::vector or
std::deque, which will grow automatically as you add data to them. They
also have functions to ensure you have enough space to hold a minimum
number of elements. However, one caveat is that each time they grow,
any pointers (or other iterators) into the container become invalid.
Would you elaborate on this a little bit. Does "... become invalid" mean
that the order and offset of the specific elements in the vector could
change and therefor the pointers/iterators become invalid or does it mean
that the order and offset of the vector-elements keep the same when adding
(push_back()) to a vector and just the references become invalid due to
some vector-internal management ?


When you push_back(), the indices of the existing elements remain the
same, however, the iterators become invalid because the elements might
be moved. Consider reserve().

Thanks in advance for your answer.
You're welcome Darius.


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To iterate is human, to recurse divine.
-L. Peter Deutsch
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Jul 22 '05 #9

P: n/a
"Darius.Moos AT esigma-systems DOT de" <pf*********@gmx.de> wrote in message news:<2i************@uni-berlin.de>...
On Thu, 03 Jun 2004 09:31:32 +0200, Dave Moore wrote:
However you can do what you want using the STL containers std::vector or
std::deque, which will grow automatically as you add data to them. They
also have functions to ensure you have enough space to hold a minimum
number of elements. However, one caveat is that each time they grow,
any pointers (or other iterators) into the container become invalid.


Would you elaborate on this a little bit. Does "... become invalid" mean
that the order and offset of the specific elements in the vector could
change and therefor the pointers/iterators become invalid or does it mean
that the order and offset of the vector-elements keep the same when adding
(push_back()) to a vector and just the references become invalid due to
some vector-internal management ?

Thanks in advance for your answer.


Well, the terse answer is that they become invalid because the
Standard says so ... I guess the correct way to interpret this is that
the Standard places no restrictions on compiler developers to make
sure that they remain valid, as it does with (for example) std::list.
What that means in the end is that, it doesn't really matter *how*
they become invalid, but rather that you can no longer rely on them to
behave in the correct way.

Sorry if this is a somewhat unsatisfying answer, but I don't really
know the guts of the STL containers, only (some of) what is in the
Standard, which is all that is required for users. There are good
books and websites to help you learn more about implementation details
if you are interested ... try www.accu.org for more info.

As far as your examples are concerned, I think that either of your
suggestions above might be a (partial) answer for a particular
implementation. Note however that if you start relying on a
particular behavior for something that is specified as undefined (or
even implementation-defined), then somewhere down the line your code
is probably going to break.

HTH, Dave Moore
Jul 22 '05 #10

P: n/a
JKop <NU**@NULL.NULL> wrote:
Jinjun Xu posted:
Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy
way to reset the length of p1? (e.g, p1 becomes int[20] and the first
10 elements keep the original value).
Imagine that this is your int[10] in memory:

char double int int int int int int int int int int char double int*
unsigned short int

What I'm getting at is that your int[10] may be boxed-in in memory. Thus,
you're *not guaranteed* that you can make it bigger!


You can't make it bigger even if it isn't "boxed in". And this is
silly because memory locations do not have types.
You'll have to find an unused bit of memory of length int[20] and
move your values.


That's what his code did.
Jul 22 '05 #11

P: n/a
"Darius.Moos AT esigma-systems DOT de" <pf*********@gmx.de> wrote:
On Thu, 03 Jun 2004 09:31:32 +0200, Dave Moore wrote:
However you can do what you want using the STL containers std::vector or
std::deque, which will grow automatically as you add data to them. They
also have functions to ensure you have enough space to hold a minimum
number of elements. However, one caveat is that each time they grow,
any pointers (or other iterators) into the container become invalid.


Would you elaborate on this a little bit. Does "... become invalid" mean
that the order and offset of the specific elements in the vector could
change and therefor the pointers/iterators become invalid or does it mean
that the order and offset of the vector-elements keep the same when adding
(push_back()) to a vector and just the references become invalid due to
some vector-internal management ?


If you push_back() and the vector has no more memory, it has to
allocate a new block. This could involve getting an entire new block
and copying the data across, rather than resizing the existing block.
Any pointers to the old block would now be indeterminate (so it could
crash your program to use them in any expression). Iterators are often
implemented as pointers, rather than offsets, so the iterators
could now be indeterminate too.
Jul 22 '05 #12

P: n/a
"Jinjun Xu" <jj**@ucla.edu> wrote in message
Suppose I have an array, e.g., int *p1 = new int[10]; is there any easy way
to reset the length of p1? (e.g, p1 becomes int[20] and the first 10
elements keep the original value).


int var = 0;
std::vector<int*> p(10);
for (int i=0; i<10; i++) p[i] = &var;
p.resize(20);

You can also call reserve(N) to ask the vector to set aside space to
grow to N elements without resizing.

std::vector<int*> p;
p.reserve(30);
p.resize(10);
for (int i=0; i<10; i++) p[i] = &var;
p.resize(20);

You can also use push_back as someone else demonstrated, and reserve
in combination with push_back.

Does anyone know if there are implementations out there for which
p.resize(N) where p is a std::vector<T> where T is a POD type calls
std::realloc(N*sizeof(T))?
Jul 22 '05 #13

P: n/a
On Thu, 03 Jun 2004 22:27:22 +0200, Old Wolf wrote:
If you push_back() and the vector has no more memory, it has to allocate
a new block. This could involve getting an entire new block and copying
the data across, rather than resizing the existing block. Any pointers
to the old block would now be indeterminate (so it could crash your
program to use them in any expression). Iterators are often implemented
as pointers, rather than offsets, so the iterators could now be
indeterminate too.


So do you agree with Prateek R. Karandikar that the indices of vector-
elements do not change by the operation you described ?

Darius.
Jul 22 '05 #14

P: n/a

"Jinjun Xu" <jj**@ucla.edu> wrote in message
news:c9**********@daisy.noc.ucla.edu...

Thank you guys for the reply and help! It was my first post in news group
and I am so happy to get the answer quickly and helpfully.

It seems that I should spend more time on learning using the classes in the C++ library instead of writing from scratch by myself. My work is on
numerical computation so I need to use vector and matrix often. What I did
is to write the classes CVector and CMatrix by myself. Now I know that
vector class may help me much. Thank you.

JJ
Glad to be of help.
Just want to point out that the STL library is not in existance to
discourage the construction of objects or the creation / coding of processes
or procedures. On the contrary, the STL library is a platform-independent,
thoroughly tested set of containers with which to create with.

If what you need is an array, then by all means create an array. You'll find
that a deque, set, bitset, priority_queue or some other STL container might
just fit perfectly to supply the underlying container for an abstract class
(for example).

"SaltPeter" <Sa*******@Jupiter.sys> wrote in message
news:hI**********************@news20.bellglobal.co m...
inline...

"Jinjun Xu" <jj**@ucla.edu> wrote in message
news:c9**********@daisy.noc.ucla.edu...
Hi,

I have an array and I want to adjust the size (remove some elements).
I use
the following code. Can you help me to check whether it's correct.

////////////// start
int *p1 = new int[oldsize];

// ....
// set the values of p1

int *p2 = p1;
p1 = new int[newsize];

// copy some values from p2 to p1
for ( i = 0; i .... )
if (....) p1[i] = p2[i];

delete []p2;

////////////// end

Suppose I have an array, e.g., int *p1 = new int[10]; is there any
easy way
to reset the length of p1? (e.g, p1 becomes int[20] and the first 10
elements keep the original value).

Thank you very much in advance for your help!

JJ


The easy way is to use a vector instead of an array. Arrays have a fixed
size limitation while a vector container dynamically resizes itself.
Additionally, all STL containers come equipped with powerful member
functions, iterators and algorithms to swap, sort, replace, append, push, pop, etc...

as a simple example using a vector of integers and a display function:

#include <iostream>
#include <vector>

void display(std::vector<int>& r_v)
{
std::cout << "vector contents:" << std::endl;

std::vector<int>::iterator it;
for (it = r_v.begin(); it != r_v.end(); it++)
{
std::cout << *it << std::endl;
}
}

int main()
{
std::vector<int> vi;

// add a few elements
vi.push_back(0);
vi.push_back(1);
vi.push_back(2);

std::cout << "vector vi has " << vi.size() << " elements" <<

std::endl;
display(vi);

// add more elements
vi.push_back(3);
vi.push_back(4);
vi.push_back(5);

std::cout << std::endl << "vector vi has " << vi.size() << " elements" << std::endl;
display(vi);

std::cout << std::endl;

return 0;
}


Jul 22 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.