How to free dynamically allocated vector? - c++

I tried to create vector of vector int, and I confused how do i free the dynamically allocated vector after.
The following is my code:
vector<int> *j;
vector< vector<int> > i; //vector of vector<int>
int c; //offset of the number
cin.ignore();
for(int count = 0; count < cas; count++ )
{
c = 0;
char line[1000];
j = new vector<int>;
cin.getline(line, 1000);
//tokenize the input string which separate by space “ ”
char *p = strtok(line, " ");
while(p != NULL)
{
n[c] = string(p);
c++;
p = strtok(NULL, " ");
}
//convert the string input to integer for further calculation
for(int m = 0; m < c; m++)
{
(*j).push_back(atoi(n[m].c_str()));
}
i.push_back(*j);
}
//this is the way i try to free the allocated vector, and i get segmentation fault for this
j = &i[0];
delete [] j;

You don't need any pointers or new or delete. These are advanced concepts that have no place in this simple program.
vector<vector<int>> i;
for (...) {
vector<int> j;
// fill up j
i.push_back(j);
}
Remember, a vector of vectors is not conceptually different from a vector of ints. You don't start new'ing and delete'ing ints when you need to fill up a vector<int>. Nor do you need to do so for any X when you work with a vector<X>.

The
i.push_back(*j);
does't push the pointer; it makes a copy of the vector.
As soon as you've done that, you can
delete j;
there and then.
(Of course if you change i to store pointers, the story will be completely different.)

Related

C++ freeing memory allocation of array with sub arrays

Theoretically, is it enough if I only delete arrays and results but don't delete sub_array inside of arrays in the following code snippet, before return 0; or do I have to first delete all the sub_array before I can safely delete arrays and results.
int main() {
int subarrays, queries;
cin >> subarrays >> queries;
int** arrays = new int* [subarrays]();
int* results = new int[queries];
for (int i = 0; i < subarrays; i++) {
int length;
cin >> length;
int* sub_array = new int[length];
for (int j = 0; j < length; j++) {
int element;
cin >> element;
sub_array[j] = element;
}
arrays[i] = sub_array;
}
for (int i = 0; i < queries; i++) {
int query_from, arr_index;
cin >> query_from >> arr_index;
results[i] = arrays[query_from][arr_index];
}
for (int i = 0; i < queries; i++) {
cout << results[i] << endl;
}
return 0;
}
You shouldn't delete sub_array because the buffer it points to is stored in arrays[n]. As the only way you could delete sub_array is inside the block scope it was declared (which is the for loop), if you do delete it then arrays[n] will be a dangling pointer (a pointer that points to a freed or invalid memory block) and dangling pointers are evil.
What you should do about arrays and sub_array is when they are not needed anymore, you first iterate through all elements of arrays, deleting each one of them and after this, delete arrays itself. Something like:
// when you are done with them
for(auto i = 0; i < subarrays; i++)
{
delete[] arrays[i];
}
delete[] arrays;
As a side-note you should consider using smart pointers in this code.
Yes, you have to first delete all the sub_array before I can safely delete arrays and results to prevent memory leak.
You can employ a loop to go through the sub-arrays in the array.

Dynamically allocating memory

I am new to C++ and programming in general so i apologize if this is a trivial question.I am trying to initialize 2 arrays of size [600][600] and type str but my program keeps crashing.I think this is because these 2 arrays exceed the memory limits of the stack.Also,N is given by user so i am not quite sure if i can use new here because it is not a constant expression.
My code:
#include<iostream>
using namespace std;
struct str {
int x;
int y;
int z;
};
int main(){
cin>>N;
str Array1[N][N]; //N can be up to 200
str Array2[N][N];
};
How could i initialize them in heap?I know that for a 1-D array i can use a vector but i don't know if this can somehow be applied to a 2-D array.
How 2-or-more-dimensional arrays work in C++
A 1D array is simple to implement and dereference. Assuming the array name is arr, it only requires one dereference to get access to an element.
Arrays with 2 or more dimensions, whether dynamic or stack-based, require more steps to create and access. To draw an analogy between a matrix and this, if arr is a 2D array and you want access to a specific element, let's say arr[row][col], there are actually 2 dereferences in this step. The first one, arr[row], gives you access to the row-th row of col elements. The second and final one, arr[row][col] reaches the exact element that you need.
Because arr[row][col] requires 2 dereferences for one to gain access, arr is no longer a pointer, but a pointer to pointer. With regards to the above, the first dereference gives you a pointer to a specific row (a 1D array), while the second dereference gives the actual element.
Thus, dynamic 2D arrays require you to have a pointer to pointer.
To allocate a dynamic 2D array with size given at runtime
First, you need to create an array of pointers to pointers to your data type of choice. Since yours is string, one way of doing it is:
std::cin >> N;
std::string **matrix = new string*[N];
You have allocated an array of row pointers. The final step is to loop through all the elements and allocate the columns themselves:
for (int index = 0; index < N; ++index) {
matrix[index] = new string[N];
}
Now you can dereference it just like you would a normal 2D grid:
// assuming you have stored data in the grid
for (int row = 0; row < N; ++row) {
for (int col = 0; col < N; ++col) {
std::cout << matrix[row][col] << std::endl;
}
}
One thing to note: dynamic arrays are more computationally-expensive than their regular, stack-based counterparts. If possible, opt to use STL containers instead, like std::vector.
Edit: To free the matrix, you go "backwards":
// free all the columns
for (int col = 0; col < N; ++col) {
delete [] matrix[col];
}
// free the list of rows
delete [] matrix;
When wanting to allocate a 2D array in C++ using the new operator, you must declare a (*pointer-to-array)[N] and then allocate with new type [N][N];
For example, you can declare and allocate for your Array1 as follows:
#define N 200
struct str {
int x, y, z;
};
int main (void) {
str (*Array1)[N] = new str[N][N]; /* allocate */
/* use Array1 as 2D array */
delete [] Array1; /* free memory */
}
However, ideally, you would want to let the C++ containers library type vector handle the memory management for your. For instance you can:
#include<vector>
..
std::vector <std::vector <str>> Array1;
Then to fill Array1, fill a temporary std::vector<str> tmp; for each row (1D array) of str and then Array1.push_back(tmp); to add the filled tmp vector to your Array1. Your access can still be 2D indexing (e.g. Array1[a][b].x, Array1[a][b].y, ..., but you benefit from auto-memory management provided by the container. Much more robust and less error prone than handling the memory yourself.
Normally, you can initialize memory in heap by using 'new' operator.
Hope this can help you:
// Example program
#include <iostream>
struct str {
int x;
int y;
int z;
};
int main()
{
int N;
std::cin>>N;
str **Array1 = new str*[N]; //N can be up to 200
for (int i = 0; i < N; ++i) {
Array1[i] = new str[N];
}
// set value
for (int row = 0; row < N; ++row) {
for (int col = 0; col < N; ++col) {
Array1[row][col].x=10;
Array1[row][col].y=10;
Array1[row][col].z=10;
}
}
// get value
for (int row = 0; row < N; ++row) {
for (int col = 0; col < N; ++col) {
std::cout << Array1[row][col].x << std::endl;
std::cout << Array1[row][col].y << std::endl;
std::cout << Array1[row][col].z << std::endl;
}
}
}

Why I can't input into my std::vector in C++

I'm a newbie in C++. I've just learnt about vector in STL.
However, when I tried to input an integer into my vector:
vector<int> v;
cin>>v[i]
The program returned segmentation fault. Please help me out.
Your vector doesn't have any elements in it, so the internal array is null. When you try to read something into it, you're trying to deference a null pointer (resulting in the segfault). Add elements to the vector first:
vector<int> v(100); //Create vector with 100 elements
for(int i = 0; i < 100; i++) {
cin >> v[i];
}
Alternatively, you could read elements into a local variable, then add them into the vector:
vector<int> v;
for(int i = 0; i < 100; i++) {
int new_val;
cin >> new_val;
v.push_back(new_val);
}

Rearranging the elements of array with specific positions

User has to make an array from any amount of numbers and I need to rearrange the array, so that the elements from EVEN places would move to the start of an array and from UNEVEN places to the end. For example A=[1,2,3,4,5,6] would turn into B=[2,4,6,1,3,5]. Also I need to use POINTERS.... I am very bad at pointers, so help would be very much appreciated.
This is as far as I got myself. I am not using pointers here though, because I don't know how to.. :(
void switcharoo(int a, int b[]){
int temp[a], j=0;
for(int i=1;i<a;i+=2){
temp[j] = b[i];
j++;
}
for(int i=0;i<a;i+=2){
temp[j] = b[i];
j++;
}
b = temp;
}
Oups, you have still to improve your C++ knowledge...
int temp[a] is not valid C++ as you have been told in comment - Variable Length Arrays are a C feature
b is passed as a pointer (an arrays decays to a pointer to its first element when passed to a function). When you write b=temp; at the end of you function, you only change a local copy... which immediately goes out of scope: in short the current code is just a no-op.
array indices start at 0
If you want to train in using pointers, you could do something like that:
void switcharoo(int a, int b[]) {
int *even = new int[a]; // allocate an array of same size
int *odd = even + a / 2; // point at the mid array element
for (int i = 0; i<a - 1; i += 2) {
*odd++ = b[i]; // odd elements in high part
*even++ = b[i + 1]; // even in low part
}
if (0 != a % 2) { // one odd element remains
*odd++ = b[a - 1];
}
even = odd - a; // make even point again to start of allocated array
odd = even; // store a copy
for (int i = 0; i<a; i++) { // copy back in original array
b[i] = *even++;
}
delete[] odd; // and delete the allocated array
}

Program declaring variables by itself

I am still a ... novice, in c++.
I don't know the name of what I am looking for but
I 've been searching a lot but can't seem to find the answer to following question:
I want to write a program that would declare demanded number of variables.
Example:
int a;
cin>>a;
Now if "a" is 5 (or any other number), I want program to declare 5 more variables,
Names do not matter but let's say...n1,n2,n3,n4,n5.
I've tried array and for loop but can't get it to work.
I got answer on Croatian forum (forum.hr) but the forum is currently offline, so I had no
time to try it out...
It was about using heap instead of stack
Thx in advance
C++ has container classes for this purpose. In particular, you want a vector:
std::vector<int> a(size);
for (int i = 0; i < a.size(); ++i)
std::cin >> a[i];
Declares a vector a of integers of some size and reads its elements, one by one.
If this is C++, the best you can do is using std::vector as it will manage the memory for you.
you can store them in an array:
int a;
cin >> a;
int *number = new int[a]; // allocate an array of size a
for (int i = 0; i < a; i++) {
number[i] = 5 + i; // set your numbers to anything here
}
delete[] number; // otherwise you have memory leak
or better use a vector:
vector<int> number(a);
// iterate with a normal for loop
for (int i = 0; i < number.size(); i++) {
number[i] = 5 + i;
}
..
// or use iterators
for (vector<int>::iterator it = number.begin(); it != number.end(); ++it) {
cout << *it << endl;
}
so you don't have to manage memory.