SEG FAULT while assigning memory to the pointer of vector of structs - c++

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.

Related

Revisited: difference between static array and dynamic array in C++?

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

C++ returning array

I am trying to wrap my mind around arrays and pointers in C++.
I am trying to write a function that allocates memory for an int array of variable size. The array is then filled with random numbers and returned.
The problem I have is assigning values with pointers.
This is the function:
int* getArray(int length) {
int* values = new int[length];
for (int i=0; i<length; i++) {
values[i]=i;
}
return values;
}
And it works just fine.
But, if I change it to this:
int* getArray(int length) {
int* values = new int[length];
for (int i=0; i<length; i++, values ++) {
*values=i;
}
return values;
}
It doesn't work.
Can someone explain to me why I cannot do this?
This is the main method that I used to print all the values:
int main() {
int* v = getArray(100);
for(int i=0;i<100;i++, v++) {
cout << *v <<endl;
}
delete[] v;
return 0;
}
I think it is because the new operator allocates new memory in the heap and not in the stack so the pointer might actually point to the wrong direction.
But, if that is true, why is the main method working?
Side note: I do not get any kind of warning or error, but the output is just a bunch of zeros and some random numbers.
I am using the GCC compiler on Ubuntu.
values++ is modifying values, which eventually forms the function return value.
i.e. you return one past the end of the allocated array. That in itself is perfectly legal C++.
But things go very badly wrong at the function call site: you access invalid elements of the array (which very informally speaking are your "random numbers"), and calling delete[] on that is also undefined behaviour. Boom!

Destruct array of vectors in C++

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.

C++ pointer to vector

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

how to return two dimensional char array c++?

i ve created two dimensional array inside a function, i want to return that array, and pass it somewhere to other function..
char *createBoard( ){
char board[16][10];
int j =0;int i = 0;
for(i=0; i<16;i++){
for( j=0;j<10;j++){
board[i][j]=(char)201;
}
}
return board;
}
but this keeps giving me error
Yeah see what you are doing there is returning a pointer to a object (the array called board) which was created on the stack. The array is destroyed when it goes out of scope so the pointer is no longer pointing to any valid object (a dangling pointer).
You need to make sure that the array is allocated on the heap instead, using new. The sanctified method to create a dynamically allocated array in modern C++ is to use something like the std::vector class, although that's more complicated here since you are trying to create a 2D array.
char **createBoard()
{
char **board=new char*[16];
for (int i=0; i<16; i++)
{
board[i] = new char[10];
for (int j=0; j<10; j++)
board[i][j]=(char)201;
}
return board;
}
void freeBoard(char **board)
{
for (int i=0; i<16; i++)
delete [] board[i];
delete [] board;
}
The best approach is create a board class and make the ctreateBoard function its constructor:
class Board {
private:
char mSquares[16][10];
public:
Board() {
for(int i=0; i<16;i++){
for( int j=0;j<10;j++){
mSquares[i][j]=201;
}
}
// suitable member functions here
};
For information on how to use such a class, there is no substitute for reading a good book. I strongly recommend Accelerated C++ by Andrew Koenig and Barbra Moo.
This approach will not work. If you return a pointer to a local variable you'll run into undefined behaviour. Instead allocate an array on heap with new and copy data into it manually indexing it.
I would really recommend using STL vector<> or boost/multi_array containers for this.
If you must use arrays, then I would recommend using a typedef to define the array.
typedef char[16][10] TBoard;
You could also return
char**
...but then you would need to typecast it to the correct size in order to index it correctly. C++ does not support dynamic multiple dimension arrays.
Also as others have suggested you can't return an object on the stack (i.e., local variable)
Don't return pointer to a local variable, as other mentioned. If I were forced to do what you want to achieve, first I'd go for std::vector. Since you haven't learnt std::vector, here is another way:
void createBoard(char board[16][10])
{
int j =0;int i = 0;
for(i=0; i<16;i++){
for( j=0;j<10;j++){
board[i][j]=(char)201;
}
}
}
You should return char** instead of char*
The simple answer to your question is char**.
Having said that, DON'T DO IT !
Your "board" variable won't last outside createBoard().
Use boost::multi_array and pass it as a reference to createBoard() or return it directly (but if you do that, it will be copied).
You must not return a pointer to a functions local variables because this space gets overwritten as soon as the function returns.
The storage associated with board is on the function's stack.