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 | |
Share this Question
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 | |
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;
} | |
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 | |
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; } | |
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. | |
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 | |
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 | |
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
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
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 | |
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. | |
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. | |
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))? | |
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. | |
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; }
| | This discussion thread is closed Replies have been disabled for this discussion. | | Question stats - viewed: 1330
- replies: 14
- date asked: Jul 22 '05
|