Mam taki dylemat. Przedstawię najpierw kod w języku C:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *wsk = (int*)malloc(10 * sizeof(int));
for (int i = 0; i < 10; ++i)
wsk[i] = 0;
free(wsk[3]); //kompiluje się z ostrzeżeniem
for (int i = 0; i < 10; ++i)
printf("%d ", wsk[i]);
}
Najpierw alokuję dynamicznie pamięć dla wskaźnika - miejsce dla 10 wartości typu int. Następnie chciałbym zwolnić pamięć, która wskazuje na czwarty element tego wskaźnika za pomocą free(wsk[3]); Dostaje tutaj ostrzeżenie od kompilatora: "free": niezgodność wskaźnika na rzeczywisty parametr 1. Następnie wyświetlam elementy tej tablicy, wszystkie 10. Okazuje się, że zwalnianie pamięci nie zadziałało. Wszystkie elementy wskaźnika wyświetliły się poprawnie. Pytanie: czy jest więc sposób albo czy jest to w ogóle możliwe zwolnić pamięć wybranych przez siebie miejsc w pamięci na które wskazuje ten wskaźnik zostawiając przy tym pozostałe?
Kolejny kod to język C++:
#include <iostream>
using namespace std;
int main()
{
int *wsk = new int[10];
for (int i = 0; i < 10; ++i)
wsk[i] = 0;
delete[(wsk+9)] wsk; //kompiluje się z błędem
//for (int i = 0; i < 10; ++i)
//cout << wsk[i] << " ";
}
Ciekawostka z tego kodu, którą teraz zauważyłem: (Visual Studio 2017 RC) kompiluje się w całości ale pokazuje błąd: Wyrażenie musi mieć typ całkowitoliczbowy lub typ wyliczenia niewystępującego w zakresie. Mimo takiego błędu program się uruchamia. Pętla for z kodu jest w komentarzu - gdyby nie on, to oczywiście mamy program crashed i błąd odczytu pamięci. Pytanie więc to samo tylko w odniesieniu do C++: Czy jest sposób albo czy jest to w ogóle możliwe zwolnić pamięć wybranych przez siebie miejsc w pamięci na które wskazuje ten wskaźnik zostawiając przy tym pozostałe?
Jednym z pomysłów na jakie wpadłem było takie kombinowanie w C++, polegające na utworzeniu dynamicznie alokowanej tymczasowej tablicy, skopiowanie tam zawartości z tablicy głównej, a następnie dealokacja i alokacja tablicy głównej, ponowne skopiowanie zawartości do tablicy głównej i na koniec dealokacja tablicy tymczasowej.
int *tab = new int[10];
for (int i = 0; i < 10; ++i)
tab[i] = 0;
int *tablica_tymczasowa = new int[9]; //utworzenie tymczasowej tablicy
for (int i = 0; i < 9; ++i)
tablica_tymczasowa[i] = tab[i]; //skopiowanie wartosci z glownej tablicy do tymczasowej bez ostatniego elementu
delete[] tab; //dealokacja pamieci glownej tablicy
tab = new int[9]; //alokacja pamieci dla nowej pomniejszonej glownej tablicy
for (int i = 0; i < 9; i++)
tab[i] = tablica_tymczasowa[i]; //skopiowanie wartosci z tablicy tymczasowej do glownej
delete[] tablica_tymczasowa; //dealokacja pamieci tablicy tymczasowej
Jednak zastanawiam się nad czymś wydajniejszym, bo przy większych ilościach elementów w tablicy takie alokacje, dealokacje, kopiowanie trochę czasu jednak zajmuje.