I have to insert elements into a pointer to a vector.I have written the following code but it is giving segmentation fault. Could someone please point out what are the errors in this code or how can we do this alternatively.
int main()
{
vector<int> *te;
te->push_back(10);
cout<<te->size()<<endl;
return 0;
}
You never allocate the vector:
vector<int> *te = new vector<int>;
Also, you don't need dynamic allocation. A cleaner way is with automatic storage:
int main()
{
vector<int> te;
te.push_back(10);
cout<<te.size()<<endl;
return 0;
}
vector<int> *te;
te->push_back(10);
You have declared a pointer to a vector; you have not initialized it to point to a valid piece of memory yet. You need to construct a new vector using new.
vector<int> *te = new vector<int>();
You should however not do this. There are very few reasons to maintain a pointer to a vector, and you just made it completely ineffective at managing its own internal memory.
Read a little bit about RAII. This is a technique used to manage dynamically allocated memory via the lifetime of an object. The vector uses this method to clean up its internal, dynamically allocated storage when it goes out of scope.
Maintaining a pointer to the vector prevents it from working correctly, relying on you to call delete yourself, essentially nullifying one major benefit of using a vector over an array in the first place.
you have to first allocate place for the pointer before starting to use it .
vector<int> *te = new vector<int>();
insert this line into your code just after the vector<int> *te;
Note that
If you were to trying to access already defined vector with an pointer you would not have to allocate place for the pointer.
For example;
vector<int> foo={1,2,3,4,5};
vector<int> * te=&foo;
te->push_back(6); // its legal.
Completing #eday solution to access elements
vector<int> foo={1,2,3,4,5};
vector<int> * te=&foo;
te->push_back(6);
cout << (*te)[2] << endl; // > 3
Your problem is that you created a pointer to a vector without creating a vector to which it points. Here's a small example where you create a vector, then use the pointer to do something to it, and then check the original vector to see the result:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> myvector;
vector<int>* te = &myvector;
int N = 5;
for(int i = 0; i < N; i++){
te->push_back(N - i);
}
cout<<"te->size() "<<te->size()<<endl;
for(int i = 0; i < N; i++){
cout<<"myvector["<<i<<"] = "<<myvector[i]<<endl;
}
return 0;
}
Related
I'm a beginner for C++ and I saw the post here. However, it is very unclear for me what is the benefit of dynamic array.
One advantage is that one can change the length of a dynamic array, here is the code
int *p = new int[10];
// when run out of the memory, we can resize
int *temp = new int[20];
copy(p, temp); // copy every element from p to temp
delete[] p; // delete the old array
p = temp;
temp = nullptr;
Above is for dynamic allocation, it says the array will be on the heap, and need to manually delete it. However, why not use the static array as follow
int array1[10];
int *p = array1;
// when run out of the memory, we can resize
int array2[20];
copy(array1, array2); // copy every elements from array1 to array2;
p = array2;
In this code, we don't need to delete the array1 since it is on the stack area. Here are my question:
what is the benefit of the dynamic array? It seems for me, resizing is not a big issue. People always say the size of static array are fixed, the size of dynamic array is not fixed. Why the size of dynamic array is not fixed. for example, int p=new int[10], the size of p is fixed.
Thanks a lot.
int array1[10];
int *p = array1;
// when run out of the memory, we can resize
int array2[20];
copy(array1, array2); // copy every elements from array1 to array2;
p = array2;
In whichever function, or inner scope, array1 and array2 get declared these arrays get automatically destroyed when the function or inner scope returns. Full stop.
This is why this is called "automatic scope". The fact that there may be a pointer to one of the arrays is immaterial. The array will be gone and any attempt to dereference that pointer will result in demons flying out of your nose.
So if you had any grand designs to continue using this array, in some form or fashion, after returning from the function where they get declared, too bad. It's not going to happen.
On the other hand, after newing something, as long as you properly track the pointer to the newed object(s) they can be used anywhere else, until they get deleted. This function, another function, anywhere. Even a different execution thread.
Having said all of that, you should not be using new or delete either. You should be using C++ library's containers which will correctly handle all memory allocation, deallocation, and copying, for you. In this case, you are simply reinventing what std::vector already does for you, and it will actually do it, in some ways, far more efficient than you can do easily on your own. You just call resize(), and, presto, your vector is bigger or smaller, as the case may be. And, in all other respects the vector will be indistinguishable from your array. It will be very hard to tell the difference.
So, use C++ library's containers. They are your friends. They want you to do memory allocation correctly, on your behalf. Modern C++ code rarely uses new or delete, any more. It's important to understand how it works, but 99% of the time you don't really need it.
Doing your own dynamic array with new int[20] and delete[] etc, is no doubt good for learning how it all works.
In real C++ programs you would use std::vector. Maybe like this:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> lines;
std::string line;
while (std::getline(std::cin, line)) {
lines.push_back(line);
}
std::cout << "Read " << lines.size() << " lines of input\n";
}
The reason you would use dynamic allocation is so your program can handle any number of lines of any line length. This program can read four lines or 400,000. The std::vector is dynamic. So is std::string.
I have write a code on static and dynamics array, hope this will help.
#include<iostream>
using namespace std;
int main (){
//creating the static array .. rember the syntax of it.
int array[4]= {1,2,3,4}; // size is fixed and can not be changeable at run time.
cout<<"Static Array."<<endl;
cout<<"Printing using index."<<endl;
for(int x=0;x<4;x++){
cout<<"\t"<<array[x];
}
cout<<endl;
cout<<"Printing using pointer."<<endl;
int*ptr= array;
for(int x=0;x<4;x++){
cout<<"\t"<<*ptr++;
}
//delete [] array ;// error, because we can not free the size from stack
// array[6]= {1,2,3,4,5,6}; //Error: We can not change the size of static array if it already defined.
// we can not change the size of the static aray at run time.
cout<<endl;
cout<<"\n\nDynamic Array."<<endl;
int n=4;
//Creating a dynamic Array, remember the systex of it.
int *array2 = new int [n]; // size is not fixed and changeable at run time.
array2[0]= 1;
array2[1]= 2;
array2[2]= 3;
array2[3]= 4;
cout<<endl;
cout<<"Printing using index."<<endl;
for(int x=0;x<4;x++){
cout<<"\t"<<array2[x];
}
cout<<endl;
cout<<"Printing using pointer."<<endl;
int*ptr2= array2;
for(int x=0;x<4;x++){
cout<<"\t"<<*ptr2++;
}
cout<<endl<<endl<<endl;
delete array2; //Size is remove at runtime
cout<<"Chnaging the size of dynamic array at runtime... :)";
// Changing the size of the array to 10.. at runtime
array2 = new int [10]; // Array size is now change to 10 at runtime
array2[0]= 1;
array2[1]= 2;
array2[2]= 3;
array2[3]= 4;
array2[4]= 5;
array2[5]= 6;
array2[6]= 7;
array2[7]= 8;
cout<<endl;
cout<<"Printing using index."<<endl;
for(int x=0;x<7;x++){
cout<<"\t"<<array2[x];
}
// free the memory/ heap
delete [] array2;
return 0;
}
Output
I have questions about the destructing process of STL vector as well as array of vectors. The only thing I learned from my teacher is the number of delete is equal to the number of new. I have 3 questions for the array of vector in different contexts. To be convenient, all of the array has 5 vectors. Each vector has 1 element.
1. Array of vectors appears in main.cpp
int main(){
int size = 5;
vector<int> *array_vec = new vector<int>[size];
for(int i=0; i<size; i++){
array_vec[i].push_back{i};
}
delete [] array_vec;
return 0;
}
Question 1: At the end of the main() function, I manually delete the array by delete [] array_vec, but I don't manually free each vectors array_vec[i]. Was the array_vec[i]'s memory released automatically? If yes, when? (before OR after my delete [] array_vec?) The reason why I ask this question is for 2D dynamic array, we must free the inner array before the outer array, so I wonder whether it is the case for the array of vector.
2. Array of vectors appears in a class's method as a temporary variable
Class myClass{
public:
void myMethod(){
int size = 5;
vector<int> *array_vec = new vector<int>[size];
for(int i=0; i<size; i++){
array_vec[i].push_back(i);
}
delete [] array_vec;
}
}
int main(){
myClass myclass;
myclass.myMethod();
/** some other process in the program **/
return 0;
}
Question 2: Was the array_vec[i] released before the myclass.myMethod() returned? OR array_vec[i] will only be released at the end of the entire program?
3. Array of vectors appears in a class as a class property
Class myClass{
public:
vector<int> *array_vec;
public:
~myClass(){
if(array_vec)
delete [] array_vec;
}
void Init(){
int size = 5;
array_vec = new vector<int>[size];
for(int i=0; i<size; i++){
array_vec[i].push_back(i);
}
}
void Use(){
std::cout<<array_vec[0][0]<<std::endl;
}
}
int main(){
myClass myclass;
myclass.Init();
myclass.Use();
/** some other process in the program **/
return 0;
}
Question 3: Is my destructor OK? In my ~myClass() method, I just free the array of vectors array_vec, but I do not know whether those vectors themselves will be free automatically or not? If yes, that will be good. If no, when will they be released? How can I manually free those vectors?
This problem has confused me for a long time. The memory issue is very important for my c++ program, because I need to use array of vectors in a big loop. If the memory is not released correctly, the memory usage will be larger and larger while the program is running. In that case, my program will crash. Really appreciate your help.
All of your examples are fine. std::vector takes care of cleaning up the memory it owns. That's why you use it instead of raw pointers.
In all of the cases you posted, you should use a std::vector<std::vector<int>> instead though. That will free you from having to deal with memory management at all, and help avoid easy mistakes, like the rule of three violation in your third example.
I don't understand pointers to pointers or pointers to 2d arrays. I do not understand what the following code does. Can anyone go line by line and explain to me what it is doing? It is really important for me to grasp this concept, but I cannot grasp it.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
//but then i'm confused why there is a pointer to a pointer when there isn't a pointer in the first place
int **tD2;
//and i am confused what the star after int does
tD2 = new int*[2];
//i think i get this
for(int i = 0; i < 2; i++)
tD2[i] = new int[2];
for(int i = 0; i < 2; i++)
delete [] tD2[i];
//lost here
delete [] tD2;
return 0;
}
I will leave comments to explain...
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
//but then i'm confused why there is a pointer to a pointer when there isn't a pointer in the first place
int **tD2; // A 1D array is an int*; int** makes an array of int*'s, which are themselves arrays (not necessarily all next to each other).
//and i am confused what the star after int does
tD2 = new int*[2]; // allocates memory for two int*'s.
/*
int* a = new int[2];
int** b = new int*[2];
int*** c = new int**[2];
See the pattern? It's one less * than the type.
*/
//i think i get this
for(int i = 0; i < 2; i++)
tD2[i] = new int[2];
for(int i = 0; i < 2; i++)
delete [] tD2[i]; // deallocates each inner array.
//lost here
delete [] tD2; // deallocate the outer array. (i.e., the array that holds the "inner arrays").
return 0;
}
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
//but then i'm confused why there is a pointer to a pointer when there isn't a pointer in the first place
int **tD2;
This defines tD2 as a pointer (the first *) to a pointer ( the second *) to an int. This isn't useful for anything yet because it is just a pointer and hasn't been pointed at anything. Until it points at something it is dangerous.
//and i am confused what the star after int does
tD2 = new int*[2];
This dynamically allocates an array of two pointers (the *) to ints and assigns this array to tD2. tD2 now points at something and is safe to use. However the array of pointers is uninitialized and dangerous.
//i think i get this
for(int i = 0; i < 2; i++)
tD2[i] = new int[2];
This loop dynamically allocates an array of two ints for each of the pointers in the array of pointers to ints allocated above to point at. Now all of the pointers are pointing at something.
for(int i = 0; i < 2; i++)
delete [] tD2[i];
Any memory you dynamically allocate should be returned to from which it came when you are done with it so the memory can be reused or eventually your program will run out of memory. delete [] returns an array and makes sure the appropriate destructors are called. This loop releases the arrays of int.
//lost here
delete [] tD2;
Releases the array of pointers to ints for the same reasons as above.
return 0;
}
Note: This is a horrible way to manage a 2D array. Look at all the work you had to do. Think of how easy it is to forget or be unable to return the memory that was allocated. The programmer has to remember the dimensions or pass them around with tD2 to make sure no one steps out of bounds.
Don't do this. Instead use std::vector.
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
vector<vector<int>> tD2(2, // outer vector contains 2 vectors
vector(2)); // inner vector contains 2 ints
return 0;
}
vector looks after the memory for you. It knows how big all of the dimensions are so it's harder to get lost. It has a method, at, that won't let you go out of bounds. It gets bigger if you need it to get bigger. Take that dynamic array! Best of all, it has libraries full of support functions for searching, sorting and manipulating. You have to be a fool not to use vector.
Don't be a fool.
If your instructor forces you to be a fool, call them a fool under your breath and pretend you are a fool until you've safely passed the class.
struct LeafDataEntry
{
void *key;
int a;
};
int main(){
//I want to declare a vector of structure
vector<LeafDataEntry> leaves;
for(int i=0; i<100; i++){
leaves[i].key = (void *)malloc(sizeof(unsigned));
//assign some value to leaves[i].key using memcpy
}
}
I am getting SEG FAULT error for this code while doing the malloc in for loop above....Any suggestions for any alternative to assign memory to the pointer in the vector of structs.
It is because you are trying to assign to a vector which does not have the elements yet. Do this instead:
for(int i=0; i<100; i++){
LeafDataEntry temp;
leaves.push_back(temp);
leaves[i].key = (void *)malloc(sizeof(unsigned));
//assign some value to leaves[i].key using memcpy
}
That way you will be accessing actual memory.
In the comments the OP mentioned that the number of elements in the array will be decided at runtime. You can set i < someVar which will allow you to decide someVar and the size of the list at runtime.
The other answer
leaves.resize(someVar) //before the loop
Is probably a better way to go though because it is likely that it will be more efficient.
You're indexing an empty vector. Try using
leaves.resize(100);
Before the loop.
In C++, Lets say I'm creating an array of pointers and each element should point to a data type MyType. I want to fill this array in a function fillArPtr(MyType *arPtr[]). Lets also say I can create MyType objects with a function createObject(int x). It works the following way:
MyType *arptr[10]; // Before there was a mistake, it was written: "int *arptr[10]"
void fillArPtr(MyType *arptr[])
{
for (int i = 0; i < 10; i++)
{
MyType myObject = createObject(i);
arptr[i] = new MyType(myobject);
}
}
Is it the best way to do it? In this program how should I use delete to delete objects created by "new" (or should I use delete at all?)
Since you asked "What is the best way", let me go out on a limb here and suggest a more C++-like alternative. Since your createObject is already returning objects by value, the following should work:
#include <vector>
std::vector<MyType> fillArray()
{
std::vector<MyType> res;
for (size_t i = 0; i != 10; ++i)
res.push_back(createObject(i));
return res;
}
Now you don't need to do any memory management at all, as allocation and clean-up is done by the vector class. Use it like this:
std::vector<MyType> myArr = fillArray();
someOtherFunction(myArr[2]); // etc.
someLegacyFunction(&myArr[4]); // suppose it's "void someLegacyFunction(MyType*)"
Do say if you have a genuine requirement for manual memory management and for pointers, though, but preferably with a usage example.
Your method places the array of pointers on the stack, which is fine. Just thought I'd point out that it's also possible to store your array of pointers on the heap like so. Youd do this if you want your array to persist beyond the current scope
MyType **arptr = new MyType[10];
void fillArPtr(MyType *arptr[])
{
for (int i = 0; i < 10; i++)
{
MyType myObject = createObject(i);
arptr[i] = new MyType(myobject);
}
}
If you do this, don't forget to delete the array itself from the heap
for ( int i = 0 ; i < 10 ; i++ ) {
delete arptr[i];
}
delete [] arptr;
If you're going to use vector, and you know the size of the array beforehand, you should pre-size the array. You'll get much better performance.
vector<MyType*> arr(10);
for (int i = 0; i < 10; i++)
{
delete arptr[i];
arptr[i] = 0;
}
I suggest you look into boost shared_ptr (also in TR1 library)
Much better already:
std::vector<MyType*> vec;
for (int i=0; i<10; i++)
vec.push_back(new MyType(createObject(i));
// do stuff
// cleanup:
while (!vec.empty())
{
delete (vec.back());
vec.pop_back();
}
Shooting for the stars:
typedef boost::shared_ptr<MyType> ptr_t;
std::vector<ptr_t> vec;
for (int i=0; i<10; i++)
vec.push_back(ptr_t(new MyType(createObject(i)));
You would basically go through each element of the array and call delete on it, then set the element to 0 or null.
for (int i = 0; i < 10; i++)
{
delete arptr[i];
arptr[i] = 0;
}
Another way to do this is with an std::vector.
Use an array of auto_ptrs if you don't have to return the array anywhere. As long as you don't make copies of the auto_ptrs, they won't change ownership and they will deallocate their resources upon exiting of the function since its RAII based. It's also part of the standard already, so don't need boost to use it :) They're not useful in most places but this sounds like a good one.
You can delete the allocated objects using delete objPtr. In your case,
for (int i = 0; i < 10; i++)
{
delete arptr[i];
arptr[i] = 0;
}
The rule of thumb to remember is, if you allocate an object using new, you should delete it. If you allocate an array of objects using new[N], then you must delete[] it.
Instead of sticking pointers into a raw array, have a look at std::array or std::vector. If you also use a smart pointer, like std::unique_ptr to hold the objects within an std::array you don't need to worry about deleting them.
typedef std::array<std::unique_ptr<MyType>, 10> MyTypeArray;
MyTypeArray arptr;
for( MyTypeArray::iterator it = arptr.begin(), int i = 0; it != arptr.end(); ++it ) {
it->reset( new MyType( createObject(i++) ) );
}
You don't need to worry about deleting those when you're done using them.
Is the createObject(int x) function using new to create objects and returning a pointer to this?. In that case, you need to delete that as well because in this statement
new MyType( createObject(i++) )
you're making a copy of the object returned by createObject, but the original is then leaked. If you change createObject also to return an std::unique_ptr<MyType> instead of a raw pointer, you can prevent the leak.
If createObject is creating objects on the stack and returning them by value, the above should work correctly.
If createObject is not using new to create objects, but is creating them on the stack and returning pointers to these, your program is not going to work as you want it to, because the stack object will be destroyed when createObject exits.