• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem podczas usuwania tablicy przy usuwaniu elementu z danego miejsca

Object Storage Arubacloud
0 głosów
592 wizyt
pytanie zadane 28 listopada 2018 w C i C++ przez Pawli Początkujący (250 p.)

Witam mam problem podczas usuwania elementu(z wybranego miejsca w tablicy) problemem prawdopodobnie  jest usuwanie tablicy (tab)

Tutaj znajduje się alokacja 2 tablic:

void create(Alko *&tab, int &size, int&size_a)
{
	if (tab == 0)
	{
		tab = (class Alko*)malloc(size * sizeof(class Alko));
	}
	else
	{
		
		Alko*a = (class Alko*)malloc((size_a + 1) * sizeof(class Alko));
		//free(a);
		for (int i = 0; i < size_a + 1; i++)
		{
			a[i] = tab[i];
		}
		
		free(tab);
		tab = a;
		
	}
}

a tu jest blok odpowiadający za usuwanie elementu z danej pozycji

void usun(Alko *&tab, int &size_a, int ktory)
{
	if (tab == 0) {
		cout << "Nie ma czego usuwac" << endl;
	}
	if (ktory > size_a)
	{
		cout << "Nie ma alkoholu o takim numerze" << endl;
	}
	else
	{
		
 		Alko *a = (Alko*)malloc((size_a -1) * sizeof(Alko));
		//Alko *a = new Alko ( size_a-1);
		int licznik = 0;
		
		for (int i = 0; i < size_a; i++)
		{
			
			if (ktory != i)
			{
				a[licznik] = tab[i];
				licznik++;
			}
		}
		
		
		free(tab);
		
		tab = a;
		size_a--;
	}
}

+tu jest dodawaniu elementów do tablicy:

cout << "Ile alkoholow chcesz dodac" << endl;
			cin >> ktory;
			create(tab, ktory, size_a);
			int i = size_a;
			for (i; i < size_a + ktory; i++)
			{
				(tab)[i].dodawanie();
			}
			size_a += ktory;
			cout << endl;

 

Program wywala się podczas  dodawanie kilku elementów do tablicy ,usunięciu elementu nr1 ,dodaniu kilku elementów i usunięciu elementu nr1. Ktoś wie jak można poradzić sobie z tym problemem? 

Z góry Dziękuje.

 

komentarz 29 listopada 2018 przez j23 Mędrzec (194,920 p.)

Jeśli tworzysz klasy na stercie, musisz (z wyjątkami) tworzyć je używając new! malloc/free + klasy to prosta droga do problemów.

komentarz 29 listopada 2018 przez Pawli Początkujący (250 p.)
Niestety wykładowca kazał zrobić to na malloc :/
komentarz 29 listopada 2018 przez j23 Mędrzec (194,920 p.)

Kazał użyć malloc do tworzenia instancji klas? Fajny wykładowca...

 

Klasa Alko musi być POD-em, żebyś mógł używać malloc/free.

2 odpowiedzi

+1 głos
odpowiedź 29 listopada 2018 przez j23 Mędrzec (194,920 p.)
wybrane 1 grudnia 2018 przez Pawli
 
Najlepsza
void usun(Alko* &tab, int &tab_size, int ktory)
{
	if (ktory >= tab_size)
	{
		cout << "Nie ma alkoholu o takim numerze\n";
	}
	else
	{
		if(tab_size == 1)
		{
			delete[] tab;
			tab = nullptr;
			tab_size = 0;
		}
		else
		{
			Alko *new_tab = new Alko[tab_size - 1];
			
			for (int i = 0, j = 0; i < tab_size; i++)
			{
				if (ktory != i)
				{
					new_tab[j++] = tab[i];
				}
			}
			
			delete[] tab;
			tab = new_tab;
			--tab_size;
		}
	}
}

Zamień malloc/free na new[]/delete[]. Wszędzie.

komentarz 29 listopada 2018 przez Pawli Początkujący (250 p.)
Niestety to też nie pomogło :(
komentarz 30 listopada 2018 przez j23 Mędrzec (194,920 p.)

Poprawiłem drobne błędy w funkcji.

 

Pokaż klasę Alko.

komentarz 30 listopada 2018 przez Pawli Początkujący (250 p.)
class Alko
{

	char rodzaj[40];
	char nazwa[40];
	int cena;

public:
	void wyswietlanie();

	void dodawanie();

};

funkcje dodawanie to:

void Alko::dodawanie()
{
	cout << "podaj rodzaj alkoholu: ";
	cin >> rodzaj;
	cout << "podaj nazwe : ";
	cin >> nazwa;
	cout << "podaj cene : ";
	cin >> cena;
}

 

komentarz 30 listopada 2018 przez j23 Mędrzec (194,920 p.)
edycja 30 listopada 2018 przez j23
void create(Alko* &tab, int size, int &tab_size)
{
	Alko* new_tab = (Alko*)realloc(tab, (tab_size + size) * sizeof(Alko));
	if(!new_tab) return;
	tab = new_tab;
	tab_size += size;
}

Nie użyłem new/delete ze względu na wymóg. Choć jeśli to ma być kod w C, to powinieneś class zamienić na struct, wywalić metody i referencje, użyć scanf/printf zamiast std::cin/std::cout.

 

Parametry size i tab_size powinny być typu size_t (zostawiłem int, żebyś nie pisał, że Ci się nie kompiluje).

komentarz 1 grudnia 2018 przez Pawli Początkujący (250 p.)

To ma być kod w cpp z użyciem malloc'ów .Wiec cała składnia jest z cpp.

Program czy na new czy na mallocach czy na  funkcji realloc wysypuje się wyrzucając błąd :

 

komentarz 1 grudnia 2018 przez j23 Mędrzec (194,920 p.)

Bez kodu trudno powiedzieć, gdzie jest problem, ale niewątpliwie psujesz pamięć sterty (przez pisanie poza nią lub free dostaje nieprawidłowy adres).

komentarz 1 grudnia 2018 przez Pawli Początkujący (250 p.)
Link do pastebina z kodem: https://pastebin.com/AgvNAU3D

Jeżeli ktoś znajdzie błąd to jest moim zbawcą bo nawet sam wykładowca nie widział tutaj błędu, a ja siedzę już kilkanaście godzin nad nim siedzę  i błędu tez nie widzę
komentarz 1 grudnia 2018 przez j23 Mędrzec (194,920 p.)
void create(Alko *&tab, size_t size, size_t tab_size)
{
	Alko * new_tab = (Alko*)malloc((tab_size + size) * sizeof(Alko));
	
	for (int i = 0; i < tab_size; ++i)
	{
		new_tab[i] = tab[i];
	}
	
	free(tab);
	tab = new_tab;
}



void creat(Pracownicy** &tab, size_t size, size_t tab_size)
{
	Pracownicy** new_tab = (Pracownicy**)malloc((tab_size + size) * sizeof(Pracownicy*));

	for (size_t i = 0; i < tab_size; ++i) new_tab[i] = tab[i];
	for (size_t i = tab_size; i < tab_size + size; ++i) 
	{
		new_tab[i] = (Pracownicy*)malloc(sizeof(Pracownicy));
	}
	
	free(tab);
	tab = new_tab;
}



void usun(Pracownicy** &tab, int &tab_size, int ktory)
{
	if (ktory >= tab_size) // obie zmienne powinny być typu size_t
	{
		cout << "Nie ma pracownika o takim numerze\n";
		return;
	}

	Pracownicy **new_tab = (Pracownicy**)malloc((tab_size - 1) * sizeof(Pracownicy*));
	
	for (int i = 0, j = 0; i < tab_size; ++i)
	{
		if (ktory != i) 
		{
			new_tab[j++] = tab[i];
		}
		else free(tab[i]);
	}

	free(tab);

	tab = new_tab;
	--tab_size;
}

Za te nazwy create, creat czy zmienna2 to bym Ci z miejsca nie zaliczył tego.

komentarz 1 grudnia 2018 przez Pawli Początkujący (250 p.)
Tak wiem,że głupie zmienne ale to był program testowy (tak wiem głupie tłumaczenie)

Dziękuję bardzo za pomoc w rozwiązaniu problemów z programem. <3
komentarz 1 grudnia 2018 przez Pawli Początkujący (250 p.)

@j23, jeszcze się tak zapytam to usuwanie dla podwójnego wskźnika usuwa ostatni element a nie dany element + przy usuwaniu dla podwójnego nie warto dodać tak samo jak dla pojedynczego ?

if(tab_size == 1)
        {
            delete[] tab;
            tab = nullptr;
            tab_size = 0;
        }

 

komentarz 1 grudnia 2018 przez j23 Mędrzec (194,920 p.)

Tak, dodaj tam

if(tab_size == 1)
{
        free(tab[0]);
        free(tab);
        tab = nullptr;
}

Zapomniałem o tym (tak to jest jak się piszę na szybko; z drugiej strony brak tego nie jest błędem, tylko malloc(0) niekoniecznie może zwrócić NULLa).

komentarz 1 grudnia 2018 przez Pawli Początkujący (250 p.)

Jeżeli chcemy dodać element w wybrane miejsce w tablicy to coś takiego powinno przejść

jednak element przed i element po to 'smieci'

Tutaj jest kod: 

void dodaj(Alko* &tab, size_t &tab_size, size_t gdzie)
{
	if (gdzie > tab_size)
	{
		gdzie = tab_size;
	}
	Alko *new_tab = (Alko*)malloc((tab_size + 1) * sizeof(Alko));
	for (int i = 0, j = 0; i < gdzie; i++)
	{
		new_tab[j] = tab[i];
	}
	
	for ( int i = gdzie + 1,j=0; i < tab_size; i++)
	{
		new_tab[j] = tab[i - 1];
	}

	free(tab);
	tab = new_tab;
	tab_size++;



}

 

komentarz 1 grudnia 2018 przez j23 Mędrzec (194,920 p.)
void dodaj(Alko* &tab, size_t &tab_size, size_t gdzie)
{
    if (gdzie > tab_size)
    {
        gdzie = tab_size;
    }

    Alko *new_tab = (Alko*)malloc((tab_size + 1) * sizeof(Alko));

    for (size_t i = 0, j = 0; i < gdzie; ++i, ++j)
    {
        new_tab[j] = tab[i];
    }
     

    for (size_t i = gdzie, j = gdzie + 1; i < tab_size; ++i, ++j)
    {
        new_tab[j] = tab[i];
    }
 
    free(tab);
    tab = new_tab;
    ++tab_size;
}

 

komentarz 1 grudnia 2018 przez Pawli Początkujący (250 p.)
Dla podwójnego będzie tak samo  dobrze myślę?
komentarz 1 grudnia 2018 przez j23 Mędrzec (194,920 p.)
Podobnie.
komentarz 2 grudnia 2018 przez wojtas_21 Nowicjusz (120 p.)

@j23,
Nie ma błędu podczas usuwania danego elementu dla  **&tab?

Z tego co widzę to ten kod usuwa ostatni element a nie wybrany, dobrze widzę? :o

komentarz 2 grudnia 2018 przez j23 Mędrzec (194,920 p.)
Nie widzę błędu. Skąd Ci się wziął ten ostatni element?
komentarz 2 grudnia 2018 przez wojtas_21 Nowicjusz (120 p.)
Wklepałem ten kod do visiala i usuwa ostatni element a przy usuwaniu 1elementu wywala błąd  :/ ten sam co @Pawli miał dla pojedynczego
komentarz 2 grudnia 2018 przez j23 Mędrzec (194,920 p.)

link <-- o tym kodzie mowa?

 

Niewykluczone, że coś wcześniej źle robisz i dopiero podczas użycia tej funkcji to wyłazi.

komentarz 2 grudnia 2018 przez wojtas_21 Nowicjusz (120 p.)

tak o tym mowa 

cout << "Którego  chcesz usunac:" << endl;
			cin >> ktory;
			ktory = ktory - 1;
			usun(tab_pracow, tab_size, ktory );
			

to jest wywoływanie robiłem to na zmodyfikowanym kodzie tym z pastebina 

oczywiście wkleiłem te twoje funkcje dla 

komentarz 2 grudnia 2018 przez wojtas_21 Nowicjusz (120 p.)

+ gdy chce usunąć 1 element to jest taki błąd 

komentarz 2 grudnia 2018 przez j23 Mędrzec (194,920 p.)

Według mnie problem jest w innym miejscu, funkcja wydaje się być OK. Spróbuj ten kod:

    Pracownicy** tab = NULL;
    int tab_size = 0;

    creat(tab, 10, tab_size);
    tab_size += 10;
    
    usun(tab, tab_size, 0);
    usun(tab, tab_size, 1);
    usun(tab, tab_size, 4);
    usun(tab, tab_size, 5);

 

komentarz 2 grudnia 2018 przez j23 Mędrzec (194,920 p.)

Jeśli zastosowałeś "poprawkę" stąd -> link, to tam powinieneś dodać linię tab_size = 0; Jej brak będzie powodować błędy. Sama poprawka nie jest potrzebna.

komentarz 2 grudnia 2018 przez wojtas_21 Nowicjusz (120 p.)
Tak dodałem  size_t tab_size = 0; to co wysłałeś jest okey więc  błąd jest chyba gdzieś indziej :// poszukam jak nic nie znajdę to się odezwę
komentarz 2 grudnia 2018 przez j23 Mędrzec (194,920 p.)

Tak dodałem  size_t tab_size = 0;

Akurat nie o tym pisałem, ale nieważne...

komentarz 2 grudnia 2018 przez wojtas_21 Nowicjusz (120 p.)
Sorki, mój błąd. Tak dodałem to
0 głosów
odpowiedź 29 listopada 2018 przez Bondrusiek Maniak (61,410 p.)

Witam,

wydaje mi się że dobrym rozwiązaniem Twojego problemu byłoby użycie funkcji C realloc()

int main (int argc, char* argv[])
{
  int *p;
 
  p = malloc(10 * sizeof(int));  /* alokacja miejsca pod 10 elementów typu int */
 
  /* ... */
 
  p = realloc(p, 20 * sizeof(int));  /* realokacja miejsca na 10 elementów typu int więcej */
 
   /* ... */
 
 free(p);  /* zwolnienie obszaru wskazywanego przez p */
}

 

komentarz 29 listopada 2018 przez RafalS VIP (122,820 p.)
Dobrym pomysłem byłoby pozbycie się alokacji dynamicznej w stylu C tylko używanie new i delete.
komentarz 29 listopada 2018 przez Bondrusiek Maniak (61,410 p.)
Racja. Zakładam że autor posta ma za zadanie użyć funkcji z C do alokowania pamięci dlatego w tym stylu podałem odpowiedź.
komentarz 29 listopada 2018 przez RafalS VIP (122,820 p.)
Też mi tak to wyglądało, ale używa referencji :P

Podobne pytania

–1 głos
2 odpowiedzi 322 wizyt
0 głosów
1 odpowiedź 150 wizyt
pytanie zadane 15 grudnia 2018 w C i C++ przez Alan Kruszyński Obywatel (1,410 p.)
0 głosów
2 odpowiedzi 373 wizyt

92,631 zapytań

141,498 odpowiedzi

319,869 komentarzy

62,011 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...