Deleting a pointer

Hello guys.I have a function that removes a pointer form array of pointers and rotate other pointer for one place left.Now if size of array is n and pointers on positions array[n-1] and array[n-2] are the same (because i have rotated array to fill a gap) how can i delete only pointer on position n-1;

1
2
3
4
5
6
7
8
9
10
11
12
13
  Remove(int k)
{
	
	
	delete array[k];
	for (int i = k + 1; i < n; i++)
          array[i - 1] = array[i];
	delete array[n - 1];//When i do this it deletes pointers  
                          //  on positions  n-1 and n-2
	--n;


}
Last edited on
Don't delete array[k];, you should delete just array[n - 1]; since that goes out of use.

1
2
3
4
	for (int i = k + 1; i < n; i++)
          array[i - 1] = array[i];
	delete array[n - 1]
	--n;

I don't see anything wrong with this. array[n-1] might have the same value as array[n-2], but you don't need to worry about array[n - 1] as it's no longer allocated by you.
I watched in my debug window and after delete[n-1] it is not only pointer on position n-1 deleted but
also a pointer on position n-2.Maybe because n-2 got value from n-1 pointer and if I delete one i can not access a variable with an another.I could simply eliminate delete array[n-1] but later on when i am calling a destructor it is deleting elements to n,and because I lowered n it would not be deleted.
it is not only pointer on position n-1 deleted but also a pointer on position n-2.
When you delete a pointer, you invalidate the data that it points to. That means any other pointers into that data are invalid too.

So it sounds to me like the problem is elsewhere. Can you post your full code?
Note:some functions(on my language Serbian)
Whole problem:I write a c++ Program that has a class Sentence that can be filled up with Tokens.
Tokens can be:array of characters,point,space or a number.So my sentence class has array of pointers type Token and Token is abstract class and parent of classes Point,Space,Number and Array of characters.I will post only my Senetece class.Also Token does not have any variables only some functions.
Sentence.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#pragma once
#include<iostream>
#include<fstream>
#include "Tacka.h"
#include"Razmak.h"
#include"Broj.h"
#include"Niz_char.h"
using namespace std;
class Recenica
{
	int n;
	Token **niz;
public:
	Recenica();
	~Recenica();
	void Upisi_u_Fajl(char * c);
	void Zameni(int i,Token *t2);
	//void Zameni(Token *t1,Token *t2);
	void Ukloni(int k);//This is Remove
	void Prosiri(int a);
	int Broj_tokena();
	int Kapacitet();

	friend istream & operator>>(istream & in, Recenica &r);
};


Sentence.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "Recenica.h"



Recenica::Recenica()
{
	n = 10;
	niz = new Token*[n];
	for (int i = 0; i < n; i++)
		niz[i] = nullptr;
}


Recenica::~Recenica()
{
	for (int i = 0; i < n; i++)
		delete niz[i];
	delete[] niz;
}

void Recenica::Upisi_u_Fajl(char * c) {
	ofstream f(c);
	if (!f.good())
	{
		cout << "Fajl se lose otvorio";
		f.close();
	}
	int pom = 0,suma=0,visetacke=0;
	bool nadjen = false;
	Tacka *t = new Tacka();
	while (niz[pom] != nullptr)
		pom++;//Akuzeje na zadje mesto popunjeno u recenici
	/////////////////////////////////////////////////////////////
	for (int i = 0; i < pom; i++)
		if (strcmp(niz[i]->Ime(), "Tacka") == 0)
		{
			nadjen = true;
			visetacke++;
			if (visetacke > 1)
			{
				Ukloni(i);
				--pom;
			}
			if (pom < n)
			
				if (niz[i + 1] != nullptr)
				{
					niz[pom] = t;
					Ukloni(i);
					--pom;
				}
				else
				{
					Prosiri(1);
					pom++;
					niz[n - 1] = t;
				}
			
		}
	if (nadjen == false)
	{
		if (pom == n)
		{
			Prosiri(1);
			niz[n - 1] = t;
			pom++;
		}
		niz[pom - 1] = t;
		
	}//ako nema tacke dodajemo
///////////////////////////////////////////////////////////////////
	if (strcmp(niz[0]->Ime(), "Niz_char") == 0)
	{
		if (niz[0]->Prvichar() > 'a' && niz[0]->Prvichar() < 'z')
			niz[0]->Dodajchar(niz[0]->Prvichar() + 'a' - 'A');

	}
	for (int i = 0; i < pom; i++)
		f << *niz[i];
	f.close();






}
void Recenica::Zameni(int i,Token *t2)//token t1 zamenjujemo tokenom t2
{
	delete niz[i];
	niz[i] = t2;
	

}
void Recenica::Ukloni(int k)
{
	
	
	delete niz[k];
	for (int i = k + 1; i < n; i++)
		niz[i - 1] = niz[i];
	//delete niz[n - 1];
	--n;


}
void Recenica::Prosiri(int a)
{
	Token **pom;
	pom = new Token*[n + a];
	for (int i = 0; i < n; i++)
		pom[i] = niz[i];
	delete[] niz;
	niz = pom;
	n = n + a;
	
	
	
}
int Recenica::Broj_tokena()
{
	int suma = 0;
	for (int i = 0; i < n; i++)
		if (niz[i] != nullptr)
			suma++;
	return suma;
}
int Recenica::Kapacitet()
{
	return n;
}
istream & operator>>(istream & in, Recenica & r)
{
	if (r.Broj_tokena() > r.Kapacitet())
		r.Prosiri(10);
	int i = 0;
	char pom[200];
	while (i < r.n)
	{
		in >> pom;
		if (pom[0] == '.')
		{
			Tacka *t = new Tacka;
			r.niz[i] = t;
		}
		else
		if (pom[0] == ' ')
		{
			Razmak *o = new Razmak;
			r.niz[i] = o;
		}
		else
		{
			//Da li su samo brojevi u nizu karaktera
			int k = 0;
			for (int j = 0; j < strlen(pom); j++)
				if (pom[k] >= '0'&&pom[k] <= '9')
					k++;
			if (strlen(pom) == k)//to znaci da je karakter sav broj
			{
				int x = atoi(pom);
				Broj *b = new Broj(x);
				r.niz[i] = b;
			}
			else
			{
				Niz_char *y = new Niz_char(pom);
				r.niz[i] = y;
			}
		}
		i++;
	}
	
	return in;
}
Last edited on
I think dhayden got the point: it might happens that sometimes more than one pointers point to the same memory area.

If "Remove()" was a method of "Token" and we can't see "Token" code, we can only speculate about what the issue could be.

Anyway, here are some hints:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// I have a function that removes a pointer form array of pointers and rotate
// other pointer for one place left.
// Now if size of array is n and pointers on positions array[n-1] and
// array[n-2] are the same (because i have rotated array to fill a gap)
// how can i delete only pointer on position n-1;
#include <chrono>
#include <exception>
#include <iostream>
#include <random>
#include <string>


void printPtop(const int* const * const ptop, int rows, int* cols);
void removeRow(int** ptop, int k, int& rows, int* cols);


int main()
{
    // Just to avoid magic numbers in short example code:
    constexpr int M_Rows { 5 };
    constexpr int M_Cols { 7 };

    int** ptop = new int*[M_Rows];

    // I assume class "Token" uses some sort of indexes like these:
    int ptop_rows { M_Rows };
    int* ptop_cols = new int[M_Cols] {};

    // Let's fill our 2D container with random data to test it:
    std::mt19937 eng ( std::chrono::high_resolution_clock::now()
                       .time_since_epoch().count() );
    std::uniform_int_distribution<> dst(1, M_Cols);

    for(int i { 0 }; i < M_Rows; ++i) {
        int cols { dst(eng) };
        ptop[i] = new int[cols];
        ptop_cols[i] = cols;
        for(int j { 0 }; j < ptop_cols[i]; ++j) {
            std::uniform_int_distribution dst(1, 9);
            ptop[i][j] = dst(eng);
        }
    }

    // Let's see what's inside:
    std::cout << "Original 2D container:\n";
    printPtop(ptop, ptop_rows, ptop_cols);

    // Now let's remove second row:
    try {
        removeRow(ptop, 1, ptop_rows, ptop_cols);   // erase the entire II row
        std::cout << "\n2D container after second row has been erased:\n";
        printPtop(ptop, ptop_rows, ptop_cols);
    } catch (std::out_of_range& e) {
        std::cout << "Erasion failed: " << e.what() << '\n';
    }
}


void printPtop(const int* const * const ptop, int rows, int* cols)
{
    for(int i { 0 }; i < rows; ++i) {
        for(int j { 0 }; j < cols[i]; ++j) {
            std::cout << ptop[i][j];
        }
        std::cout << '\n';
    }
}


void removeRow(int** ptop, int k, int& rows, int* cols)
{
    if(k >= rows) {
        throw std::out_of_range(
                    std::string("Cannot delete beyond "
                                + std::to_string(rows - 1))
                );
    }
    delete ptop[k];
    for (int i { k }; i < rows - 1; ++i) {
        ptop[i] = ptop[i + 1];
        cols[i] = cols[i + 1];
    }
    ptop[rows - 1] = nullptr;
    cols[rows - 1] = 0;
    --rows;
}


Output:
Original 2D container:
65
2997364
852
8176636
5978

2D container after second row has been erased:
65
852
8176636
5978

Lines 65 and 68 assign the same pointer to different locations in niz. So when you delete one, you invalidate the other.

In Prosiri, you need to set pom[n] through pom[n+a-1] to nullptr.

I'm not sure about the rest of the code. It's hard for me to follow when the variables aren't in English. Sorry. :(
heh guess the rest of the world feels that way all the time, esp when we use shorthand English variables that can't be run thru a word translator.
Thank you all for your replies.
Topic archived. No new replies allowed.