Funkcje wywoływane kilka razy w pętli powodują zrzut pamięci – dlaczego?

0

Witam,
Napisałem sobie takie funkcje:

void fun1(int *t)
{
	menu(t);
}

void menu(int *t)
{
	int odp = 0;
	int *liczba = new int;

	std::cout << "Wybierz opcje:\n1-Dodaj, 2-Odejmij\n";
	cin >> odp;
	cin >> *liczba;

	unsigned int *d = dodawanie(liczba, odp);
	delete[] d;
}

unsigned int *dodawnie(int *liczba, int odp)
{
	unsigned int *wyniki = new unsigned int[3];

	if(odp == 1)
	{
		for(int i=0; i<10; i++)
		{
			wynik[i] = *liczba+i;	
		}		
	}
	else if(odp == 2)
	{
		for(int i=0; i<10; i++)
		{
			wynik[i] = *liczba+i;	
		}
	}
	return wyniki;
}

Gdy uruchomię ją w pętli kilka razy, to pojawiają się czasami dziwne wyniki, a po jakimś czasie następuje zrzut pamięci. Co robię nie tak? Czy błąd jest w tym zapisie?

unsigned int *d = dodawanie(liczba, odp);
delete[] d;
2

Nie wyłazisz poza tablicę w pętli?

2

Najpierw robisz to:

unsigned int *wyniki = new unsigned int[3];

a potem wykraczasz poza zakres tutaj:

        for(int i=0; i<10; i++)
        {
            wynik[i] = *liczba+i;   
        }  

Poza tym po kiego grzyba używasz new i delete?

0

A ten zakres zapomniałem zmienić, bo sprawdzałem czy to od niego nie zależy. Ma być 10 w obu miejscach.

No new używam, żeby program zrobił miejsce dla tablicy, a delete jak chcę posprzątać pamięć po tablicy jak już nie będę chciał z niej korzystać.

7

Ale po co? Od tego masz std::vector i inne metody by nie używać new/delete.
Te twoje dodawnie jest bezsensu, jest przekombinowane ponad miarę, a nic nie robi.
Przykładowo jaka jest różnica dla odp=1 i odp=2? Żadna.
Co jest zwracane w tej tablic? Coś zupełnie bezsensu.

3

na przyszłość odpal programik z debbugerem to ci powinno pomóc.

0
MarekR22 napisał(a):

Ale po co? Od tego masz std::vector i inne metody by nie używać new/delete.
Te twoje dodawnie jest bezsensu, jest przekombinowane ponad miarę, a nic nie robi.
Przykładowo jaka jest różnica dla odp=1 i odp=2? Żadna.
Co jest zwracane w tej tablic? Coś zupełnie bezsensu.

To jest taki przykład czysto edukacyjny, bo chciałem zobaczyć jak zachowa się w takim przypadku program, na nic innego nie miałem pomysłu

Czyli z użyciem vector powinien mój przypadek wyglądać tak?

void fun1(int *t)
{
    menu(t);
}
 
void menu(int *t)
{
    int odp = 0;
    int *liczba = new int;
 
    std::cout << "Wybierz opcje:\n1-Dodaj, 2-Odejmij\n";
    cin >> odp;
    cin >> *liczba;
 
    std::vector <int> d = dodawanie(liczba, odp);
}
 
unsigned int *dodawnie(int *liczba, int odp)
{
    std::vector <int> *wynik;
 
    if(odp == 1)
    {
        for(int i=0; i<10; i++)
        {
            wynik.push_back( *liczba+i);   
        }       
    }
    else if(odp == 2)
    {
        for(int i=0; i<10; i++)
        {
            wynik.push_back(*liczba-i);   
        }
    }
    return wynik;
}

Głównie chodzi mi o to, żeby funkcja w sobie tworzyła tablicę, na niej są przeprowadzane operacje(nie wiem jeszcze jakie), a potem ją zwraca w innym miejscu, w innej funkcji.
Może źle rozumiem metodę jaką trzeba to zrobić, jak tak to proszę o wyjaśnienie jak to zrobić poprawnie i zgodnie ze sztuką programistyczną.

2

Wiesz jak coś ma napisane "dodawanie" to powinno być to dodanie związane z argumentami tej funkcji.
Tak samo nie używaj int* jeśli to nie jest potrzebne. Nie wiem co ma robić argument odp, więc na zasadzie domyślania się zmieniam go na r:

std::vector<int> arithmeticProgression(int startValue, int r = 1)
{
      std::vector<int> result;
      for (int i = 0; i < 10; ++i)
      {
             result.push_back(startValue + i * r);
      }
      return result;
}

Ciężko się poprawia kod, który nie wiadomo co właściwie ma robić.

2

1. Prawie, ale niepotrzebnie znów używasz wskaźnik: std::vector <int> *wynik; to daje Ci wskaźnik na vector, a nie po prostu vector, dlatego usuń tą gwiazdkę.
2. jeśli już używasz gwiazdki, to musisz używać operatora -> zamiast zwykłej kropki. Musisz też pamiętać o alokacji i dealokacji zasobów pod tym wskaźnikiem, a obecnie tego w ogóle nie ma.
3. funkcja określona jest jako zwracająca typ wskaźnikowy na unsigned int, jednak Ty tworzysz w niej vector i ten zwracasz - to się nawet nie skompiluje. Określ zwracany typ jako vector.

Pomijam już logikę Twojego programu, bo chociaż jest troszkę bez sensu, to jest to osobny temat.

1 użytkowników online, w tym zalogowanych: 0, gości: 1