Skocz do zawartości
Zamknięcie Forum PC LAB

Szanowny Użytkowniku,

Informujemy, że za 30 dni tj. 30 listopada 2024 r. serwis internetowy Forum PC LAB zostanie zamknięty.

Administrator Serwisu Forum PC LAB - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie: wypowiada całość usług Serwisu Forum PC LAB z zachowaniem miesięcznego okresu wypowiedzenia.

Administrator Serwisu Forum PC LAB informuje, że:

  1. Z dniem 29 listopada 2024 r. zakończy się świadczenie wszystkich usług Serwisu Forum PC LAB. Ważną przyczyną uzasadniającą wypowiedzenie jest zamknięcie Serwisu Forum PC LAB
  2. Dotychczas zamowione przez Użytkownika usługi Serwisu Forum PC LAB będą świadczone w okresie wypowiedzenia tj. do dnia 29 listopada 2024 r.
  3. Po ogłoszeniu zamknięcia Serwisu Forum od dnia 30 października 2024 r. zakładanie nowych kont w serwisie Forum PC LAB nie będzie możliwe
  4. Wraz z zamknięciem Serwisu Forum PC LAB, tj. dnia 29 listopada 2024 r. nie będzie już dostępny katalog treści Forum PC LAB. Do tego czasu Użytkownicy Forum PC LAB mają dostęp do swoich treści w zakładce "Profil", gdzie mają możliwość ich skopiowania lub archiwizowania w formie screenshotów.
  5. Administrator danych osobowych Użytkowników - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie zapewnia realizację praw podmiotów danych osobowych przez cały okres świadczenia usług Serwisu Forum PC LAB. Szczegółowe informacje znajdziesz w Polityce Prywatności

Administrator informuje, iż wraz z zamknięciem Serwisu Forum PC LAB, dane osobowe Użytkowników Serwisu Forum PC LAB zostaną trwale usunięte ze względu na brak podstawy ich dalszego przetwarzania. Proces trwałego usuwania danych z kopii zapasowych może przekroczyć termin zamknięcia Forum PC LAB o kilka miesięcy. Wyjątek może stanowić przetwarzanie danych użytkownika do czasu zakończenia toczących się postepowań.

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

Cabalerio

[C++] Realokacja pamięci a operator new

Rekomendowane odpowiedzi

Zastanawiam się w jaki sposób doalokować pamięć na przykład do obsługi stosu w momencie jak dodajemy nowy element. Jak sobie zrobię

int a = new int[10]

a później po dodaniu 10 elementów będę chciał wstawić 11 to mam lipę. Chodzi o to czy da się doalokować pamięć nie poprzez

int b = new int[20]
for(int i = 0; i < 10; i++)
   b[i] = a[i]
delete [] a

Da się takie coś zrobić ? Czy powyższy przykład jest jedynym rozwiązaniem(jeśli tak to czy może wydajniej będzie użyć malloc i realloc) ?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Zamiast przepisywać w pętli możesz dać memcpy i różnicy względem realloca nie powinno być. No i najlepiej zwiększać tablicę o wielokrotności pewnej liczby (np. 10, 20, 40, 80), żeby za często tych danych nie kopiować

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

a nie lepiej stl vector? I nie bawić się w tu jakieś przepisywanie itp. On się tu wewnętrznie zajmie alokacją pamięci z tego co pamiętam.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Problem w tym ze mam użyć tablicy do przechowywania danych.

 

Mam kod i memcpy nie działa(kopiuje tylko 1 element), tylko muszę kopiować element po elemencie w konstruktorze kopiującym.

 

class stos
{
int nodesCount;
int *data;

public:
	stos()
	{
		nodesCount = 0;
		data = new int[10];
	};

	stos(const stos & s)
	{
		nodesCount = s.nodesCount;
		data = new int[s.nodesCount+10];

		memcpy(data, s.data, s.nodesCount+1);
		/*
		for(int i = 0; i < s.nodesCount; i++)
		{
			data[i] = s.data[i];
		}*/
	}

	~stos()
	{
		delete [] data;
	};

	// doklada
	void operator<< (int a)
	{
		if(nodesCount >= 0)
			data[nodesCount++] = a;	
		//else
	};

	//pobiera
	void operator>> (int & a)
	{
		if(nodesCount > 0)
			a = data[--nodesCount];

	};
};

 

Nie patrzcie na resztę bo pisze tylko do testów, a podałem cały kod żeby było wiadomo ocb. Może ja źle używam tego memcpy ?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nudzi mi się, więc machnąłem ;) W zasadzie 2 istotne rzeczy:

1. Sprawdzenie, czy trzeba zaalokować więcej pamięci powinno się robić przy próbie dodania nowego elementu, a więc w operatorze <<

2. memcpy kopiuje podaną ilość bajtów, a nie elementów, więc trzecim parametrem nie może być ilość elementów tablicy do przekopiowania(no chyba że element ma rozmiar 1B)

 

#include <cstring>
#include <iostream>

class stos
{
int allocated, used;
int *data;
static const int BLOCK = 10;

public:
		stos()
		{
			data = new int[bLOCK];
			used = 0;
			allocated = BLOCK;
			std::cerr << "Initial state: used=" << used << "; allocated=" << allocated << std::endl;
		};

		~stos()
		{
			delete [] data;
		};

		stos& operator<< (const int& a)
		{
			std::cerr << "Trying to add: " << a << std::endl;

			if(used < allocated) {
				data[used++] = a;
				std::cerr << "Elem added: " << a << "; used=" << used << "; allocated=" << allocated << std::endl;

				//warto zwracać stos& z tego operatora, przez co będzie mozna dodawać kilka elementów w jednej linii(zobacz main)
				return *this;
			} else {
				std::cerr << "Reallocation needed...";

				//alokacja nowej, wiekszej tablicy
				int* newData = new int[allocated + BLOCK];

				//memcpy operuje na bajtach, więc musimy kopiować ilość bajtów, a nie elementów
				memcpy(newData, data, used*sizeof(int));

				//usunięcie starej tablicy, żeby nie ciekło po nogawkach
				delete [] data;

				//ustawienie wskaźnika na nową, powiększoną tablicę
				data = newData;

				//zwiększenie zmiennej zawierającej informację jaką ilością miejsca aktualnie dysponujemy
				allocated += BLOCK;

				std::cerr << " Allocated " << BLOCK << " additional empty stack elements\n";

				//dodanie elementu przez rekurencyjne wywołanie operatora
				return operator<<(a);
			}
		};

		void out() const {
			for(int i=0;i<used;++i) {
				std::cout << data[i] << " ";
			}

			std::cout << std::endl;
		}
};

int main() {
stos s;
s << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11;
s.out();

s << 12 << 13 << 14 << 15 << 16 << 17 << 18 << 19 << 20 << 21 << 23 << 24 << 25;
s.out();

return 0;
}

 

I w zasadzie jeszcze jedna rzecz, przekazuj parametry jako stałe referencje. Zapobiegnie to tworzeniu niepotrzebnej kopii, jesli "int" zamieniłbyś na jakiś inny typ, którego kopiowanie jest kosztowne.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Całkiem ciekawy jest ten pomysł z kilkoma operatorami w jednej linii. A memcpy to naprawdę głupi błąd zrobiłem, dzięki za naprostowanie :).

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...