delete element inside pointers array (resize) - c++

Im trying to understand pointers, below my code:
int main()
{
int size = 5; //Size of array
int position = 2; //Position to delete
int *pointer = new int[size]; //Pointer declaration
//Populates array with numbers starting at 1 up to size elements (5 in this case)
for (int i = 0 ; i < size; i++)
{
pointer[i] = i+1;
}
//Prints existing elements (numbers 1 to 5 in this case)
for (int i = 0 ; i < size; i++)
{
std::cout << pointer[i] << ", ";
}
return 0;
}
I know that if I do delete [] pointers; it will delete the array from the memory, but how can I delete just the object inside position 2 or resize the array?

You can't do either of those things. You can move items around within your existing allocation, and you can make a new allocation, copy items over, and delete the old allocation.
To work with data you should use a container called vector which provides member functions to remove an element or resize. A vector is the equivalent in C++ of what most other languages call an "array".

Related

why am I consistently getting malloc errors when I try to delete my 2D array made using pointers?

I'm trying to delete my 2D array, but I consistently get errors when I try to delete it, we have to work backwards so I delete the elements first, then the column array, then the row array. here is my code for the constructor in my class, MyMatrix:
private:
int m; //rows
int **ptr; //ptr to first dimension
int n; // columns
public:
MyMatrix() //constructor
{
m = 0;
n = 0;
ptr = new int*[m];
int *length_arr = new int[m];
for (int i = 0; i <= m-1; i++)
{
*(ptr+i) = new int[n];
*(length_arr+i) = n;
}
}
and my destructor looks like this:
for(int i = 0; i <= m-1; i++)
{
for (int j = 0; j <= n-1; j++)
{
delete ((*(ptr+i))+j);
}
delete[] *(ptr+i);
}
delete[] ptr;
the error I'm getting is:
assg7(2677,0x100de3d40) malloc: *** error for object 0x12d606804: pointer being freed was not allocated
I've wracked my brain for where I can fix this, for context, I'm doing an assignment with operator overloading. I specifically need a delete function to work properly for my = assignment overloading since I want to delete and again reallocate memory to equate two matrices, but the terminal is showing malloc errors and is thus not equating the matrices.
for additional info here is my = overloading code:
void operator = (const MyMatrix &obj)
{
if(n == obj.n && m == obj.m)
{
//for loop to equate elements in this-> to the elements of the passed object
}
else
{
for(int i = 0; i <= m-1; i++)
{
for (int j = 0; j <= n-1; j++)
{
delete ((*(ptr+i))+j);
}
delete[] *(ptr+i);
}
delete[] ptr;
// the code for assigning new memory according to the passed objects rows and colums goes here
//then for loop to equate elements in this-> to the elements of the passed object
}
}
thanks.
You have two "levels" of new, so three "levels" of delete can't be right.
Spell out your deletion loop, using indexing instead of pointer arithmetic:
First iteration:
delete ptr[0]+0;
delete ptr[0]+1;
...
delete ptr[0]+n-1;
delete [] ptr[0];
Second iteration:
delete ptr[1]+0;
delete ptr[1]+1;
...
delete ptr[1]+n-1;
delete [] ptr[1];
You're passing to delete a pointer to the first element of ptr[0], a pointer to the second element of ptr[0], a pointer to the third element of ptr[0], ...
But the things you allocated were ptr[0], ptr[1], ... ptr[m-1], not their individual elements.
Remove the innermost deletion loop.
(And don't mess around with pointer arithmetic when you can use indexing.)
I don't know how you would want to allocate memory space by m length if it is set to 0 by default.
To me it looks like you set m = 0 and then try to allocate by 0 length or how do you control the length of your dimensions?
Maybe edit your constructor to:
MyMatrix(int m, int n)
{
this->m = m;
this->n = n;
...

Pointers array, deleting and asigning to it pointers in C++

My problem is when I declare an array int** arr =new* int[n] and I want to assign to it pointer to array and later change that pointer to a different pointer which is copy of it values + one other number ,it brakes down and appears (probably) infinite loop . Can you say how to do this in proper way using some low tools with c++/c or can you correct my code?
Additional explenation: the code is producing very simple output but it is not important. I want to create program to change in array pointer(int*arr) in specific index pointer to diffrent pointer . But additionally pointers direct first element in arrays .Also diffrennce beetween new and old array (which is changed in int**arr in index for example 0) is that new is bigger on a new element (int this case new number).So this output is only checking if it works.
Below is my whole code
#include <iostream>
using namespace std;
void stepwise_fill_array(int ** arr, int N, int index)
{
for(int j=1;j<=10;j++)
{
int* poi=arr[index];//getting pointer to array which i wannna change
int size=0;
while(poi){poi++;size++;}//getting size of pointer array from arr
int* n= new int[size+1];//declaring the new array
for(int i=0; i<size;i++)//copying from all values from old array to new one
n[i]=poi[i];
delete[] poi;
n[size]=j;//adding to the end new value
arr[index]=n;//asigning arr[0] to new diffrent array
}
for(int i=0;i<10;i++)
cout<<arr[0][i]<<" ";
//should print 1 2 3 4 5 6 7 8 9 10
}
int main(){
int N = 10; // how big array should be and how many times it should expand
int** arr = new int*[N];//declaring our array to pointer
for(int i=0;i<N;i++)
{
arr[i]=nullptr;
}
int index =0;//index where I would change the pointer of arr
stepwise_fill_array(arr,N,index);
}
In advance thanks for your help :)
Your style of coding and explaining of problem is tragic , but fortunately I copied with it. When you are trying to get size from while(poi){poi++;size++;} you are getting in trouble. In C\C++ is no possibility to check size of array from pointer to this array. Instead you need increment size in every iteration of function stepwise_fill_array.
Below I give you correct solution(in code are leaks but I doesn't affect in much way on efficiency):
void stepwise_fill_array(int **arr, int N, int index)
{
int size = 0;
for (int j = 1; j <= 10; j++)
{
int *poi = arr[index]; //getting pointer to array which i wannna change
int *n = new int[size + 1]; //declaring the new array
for (int i = 0; i < size; i++)
{
n[i] = poi[i]; //copying from all values from old array to new one
}
n[size] = j; //adding to the end new value
arr[index] = n; //asigning arr[0] to new diffrent array
size++;
}
for (int i = 0; i < 10; i++)
cout << arr[0][i] << " ";
//should print 1 2 3 4 5 6 7 8 9 10
}

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

Pushing element to dynamically allocated pointer array int C++

[EDIT 1] I'll preface by saying that for this project, I am required to "Create a container class" where I can push, pop, and retrieve elements from a list. I am supposed to use pointers, and must write the functions for pushing, popping, etc. [/EDIT 1]
I am having difficulty pushing an element to a dynamically allocated pointer array. I am able to initially create an array just fine. You can see from my comments my thought process for how I think I should be able to add to the array:
1) create new array with room for the one new element;
2) add the new element to index 0;
3) copy the old array into the rest of the new array;
4) delete old array;
5) set the new array as the value of the pointer
I have the following three files:
IntegerList.h:
/**
*IntegerList.h
*/
#ifndef IntegerList_H
#define IntegerList_H
class IntegerList
{
private:
int * pArray;
int length;
public:
IntegerList(); // default constructor
void createArray(int howlong);
int getValue(int index);
void deleteArray();
void pushFront(int element);
};
#endif
IntegerList.cpp:
/**
* IntegerList.cpp
*/
#include "IntegerList.h"
#include <iostream>
using namespace std;
// IntegerList constructor:
IntegerList::IntegerList()
{
pArray = 0;
length = 0;
}
// creates an array of length howlong (determined by main.cpp); sets the values
// to equal ten times the index number. For example, if an array of size 4 is
// to be created, then an array with the following values will be created by
// this method: 0, 10, 20, 30. Sets length equal to howlong.
void IntegerList::createArray(int howlong)
{
length = howlong;
pArray = new int[length];
for (int i = 0; i < length; i ++)
pArray[i] = (i*10);
}
int IntegerList::getValue(int index)
{
return pArray[index];
}
void IntegerList::deleteArray()
{
delete[] pArray;
}
// places element at front of array
void IntegerList::pushFront(int element)
{
// create new array with room for the one new element
int newArray[length+1]; // nope
// start by adding the new element
newArray[0] = element;
// copy the old array, put it into the new array starting at index 1 (since
// index 0 is the new element)
for(int i = 0; i < length; i ++)
{
newArray[i+1] = pArray[i];
}
// delete old array
deleteArray();
// set pArray equal to the new array;
pArray = newArray;
// update the value of length
length += 1;
}
And my main file, main.cpp:
#include "IntegerList.h"
#include <iostream>
using namespace std;
int main()
{
// create object
IntegerList myArray;
// create array of length 5
myArray.createArray(5);
// print array
for (int i = 0; i < 5; i ++)
cout << "Element " << i << ". " << myArray.getValue(i) << endl;
// everything works ok so far
// push the number 99 to front
myArray.pushFront(99);
// print array
for (int i = 0; i < 6; i ++)
cout << "Element " << i << ". " << myArray.getValue(i) << endl;
myArray.deleteArray();
}
The first printArray() shows that everything is going as planned. However, after I try to push 99 to the front, things get screwed up :(
Here is the output I'm getting:
Element 0. 0
Element 1. 10
Element 2. 20
Element 3. 30
Element 4. 40
Element 0. 99
Element 1. 0
Element 2. 2130567168
Element 3. 4486648
Element 4. 2686508
Element 5. 4201772
Note that in the second printout, the first two elements appear to have the value that I intended for them to have.
Any suggestions?
I'm not sure if you can force your way to make static arrays of variable length, but it's in violation of standard.
int newArray[length+1];
will not work. Make it
int * newArray = new int[length+1];
instead.
As others in comments said, reallocating an array after every single insert is extremely inefficient and tedious work. Consider using some of these:
std::vector
std::stack (as you're inserting on the beginning of your container)
std::list
your very own linked list
I rewrote the code for pushing and got it to work properly. Revised code is below. Notice I had to assign the values form the tempArray back into the "original" array (pArray), not the address of tempArray.
void IntegerList::push(int value){
// when this method is called to push a value onto an empty array, that is,
// when length = 0, it first creates an array of length 1
if(length == 0)
pArray = new int[1];
// create temp array
int * tempArray = new int[length+1];
// add new value to index 0
tempArray[0] = value;
// add old elements
for(int i = 0; i < length; i++)
tempArray[i+1] = pArray[i];
delete[] pArray;
// initialize pArray with proper size
pArray = new int[length+1];
// copy elements of tempArray into pArray
for(int i = 0; i < length+1; i++)
pArray[i] = tempArray[i];
delete[] tempArray;
length += 1;
} // end push

dynamic array change size

I created this function to change the size of the dynamic array
size = 4; //this is what size is in my code
int *list = new int[size] // this is what list
void dynArray::doubleSize( )
{
int *temparray;
int currentsize = size;
int newsize = currentsize * 2;
temparray = new int[newsize];
for (int i = 0 ; i < newsize;i++)
{
temparray[i] = list[i];
}
size = newsize;
delete [] list;
list = new int[size];
list = temparray;
// this it help see if i made any changes
cout << sizeof(temparray) << "temp size:\n";
cout << sizeof(list) << "list size:\n";
cout << size << "new size:\n\n\n";
}
I want it to output the size of array is the function each time it changes size.I know this can be done with vectors but I would like to understand how to do it with arrays
what can I do differently to make this happen.
You can't: the C++ Standard provides no mechanism to access dynamic array dimensions. If you want to know them, you have to record them when creating the array, then look at the variables you set (much as you've got size hanging around for printing at the end of your program.
Problems in your code:
Problem 1
The following for loop accesses list using out of bound indices. Number of element in list is size, not newSize.
for (int i = 0 ; i < newsize;i++)
{
temparray[i] = list[i];
}
You need to change the conditionals to i < size;.
Then, you need to figure out how how to initialize the rest of the items in temparray.
Problem 2
The following lines cause a memory leak.
list = new int[size];
list = temparray;
You allocate memory using new and immediately lose that pointer in the second line.
Answer to your question
To print the new size, you can use:
cout << "new size: " << size << "\n";
However, I wouldn't recommend putting such code in that function. You are making your class dependent on std::cout for not much benefit, IMO.