Błąd podczas kompilacji

0

Hej,

Czy mógłby ktoś wyjaśnić i jak naprawić kod, aby ten błąd już się nie pokazywał?

Unhandled exception at 0x0022CD19 in zoo.exe: 0xC00000FD: Stack overflow (parameters: 0x00000000, 0x01C02000).

Czyżby to było coś związanego ze stosem?

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdio>

using namespace std;

#define MAXN 1000010
#define min(a,b) ((a) < (b) ? (a) : (b))

int i, j, m, n, x;
int kon[MAXN], mas[MAXN], odw[MAXN], poc[MAXN], tab[MAXN];
long long il, minc = 6500, mins, sum, wyn;

int main()
{
	fstream text("input.in");
	int mas[MAXN];
	int minc = 6500;
	vector<int> numbers;
	int n = numbers[0];
	int integer, i = 0;

	while (text >> integer)
	{
		numbers.push_back(integer);
		i++;
	}

	for (i = 1; i <= n; ++i)
	{
		numbers[i] = mas[i];
		minc = min(minc, mas[i]);
	}
	for (i = n; i <= n + n; ++i)
		numbers[i] = poc[i];
	for (i = n + n; i <= n + n; ++i)
		numbers[i] = kon[i];
	for (i = 1; i <= n; ++i)
		tab[poc[i]] = kon[i];
	for (i = 1; i <= n; ++i)
		if (!odw[i])
		{
			j = i;
			mins = 6500;
			il = 0;
			sum = 0;
			while (!odw[j])
			{
				mins = min(mins, mas[j]);
				odw[j] = 1;
				++il;
				sum += (long long)mas[j];
				j = tab[j];
			}
			wyn += (long long)min(sum + (il - 2)*mins, sum + mins + (il + 1)*minc);
		}
	cout << wyn;
	system("pause");
	return 0;
}
3

Całkiem nie wiem, gdzie ten błąd występuje, bo nie znam się na C++, ale:

  1. Błędem jest ten błąd: https://pl.wikipedia.org/wiki/Przepe%C5%82nienie_stosu
  2. Nieużywanie klamer przy pętlach for to – dla mnie – proszenie się o kłopoty.
  3. Jeśli masz możliwość, używaj bardziej opisowych nazw zmiennych (niekoniecznie nawet dla kogoś, czasem po prostu żeby swój własny kod zrozumieć po jakimś czasie).

UPDATE: Przy okazji znalazłem bardzo przydatne (w mojej opinii) wskazówki dotyczące zapisu kodu: https://www.gnu.org/prep/standards/html_node/Syntactic-Conventions.html#Syntactic-Conventions Może Ci się przydadzą. :) (Dokładnie dotyczą języka C, nie C++).

0

Okej, naprawiłem już błąd ze stosem.
Teraz wyskakuje coś takiego:

error C2065: 'poc': undeclared identifier

itd itd
mimo iż już jest zdefiniowany

1

Co do komentarza – nie, po define nie daje się średnika.

https://stackoverflow.com/a/40460761

A także:
http://www.cplusplus.com/doc/tutorial/preprocessor/

No semicolon (;) is expected at the end of a preprocessor directive.

2

Jeśli to C++ to może warto w ogóle pozbyć się #define?

1

Ale tu w ogóle stos się przepełnia, bo masz jakieś ogromne rozmiary tablic... Użyj wektorów (vector), co?

1

Na ideone.com środowisko uruchomieniowe mówi, że tu jest błąd:

for (i = 1; i <= n; ++i)
	{
		numbers[i] = mas[i];
		minc = min(minc, mas[i]);
	}

Bo ten fragment nie chce się wykonać.

https://ideone.com/vj6wFY

2
fstream text("input.in");

Otwierasz plik i nie sprawdzasz czy otworzył się poprawnie.

Zamiast

#define MAXN 1000010
const int maxn = 1000010;

Błędy w instrukcjach preprocesora są trudne do interpretacji, więc lepiej używać const.

Zamiast tej instrukcji

#define min(a,b) ((a) < (b) ? (a) : (b))

lepiej napisać funkcję

int min(int a, int b) { return (a < b) ? a : b; }

lub dla dowolnego typu danych napisz szablon funkcji
http://en.cppreference.com/w/cpp/language/function_template
To co wyżej.

.

int i, j, m, n, x;
int kon[MAXN], mas[MAXN], odw[MAXN], poc[MAXN], tab[MAXN];
long long il, minc = 6500, mins, sum, wyn;

Używanie zmiennych globalnych bez wyraźnego powodu jest złą praktyką.
Do tego, jak wspomniał @Silv, używaj opisowych nazw.

Znasz

vector<int> numbers;

więc, nie męcz się z gołymi tablicami, tylko użyj std::vector i z głowy będzie problem stack overflow.
Zresztą od C++11 dostępna jest klasa std::array, aby nie trzeba było korzystać z gołych tablic
i jest bezpieczniejsza w użyciu (ma metodę .at(idx) oraz nie trzeba martwić się przekazywaniem
rozmiaru tablicy w inne miejsca).
http://en.cppreference.com/w/cpp/container/array

2
@Silv napisał(a):

Czy prócz tego, że można, a to dobry powód – to jest jakiś inny, żeby się pozbywać

Tak, define to raczej zło (konieczne w C). Nie jest kompilowane, więc nie jest poddane kontroli typów, a i składniowej tylko w ograniczonym zakresie. Stałe pisać należy w C++ za pomocą const, a funkcje typu makro -- za pomocą inline (o ile się da).

PS. Dyskusja na temat nie w komentarzach. :)

0

Tak w ogóle mam jeszcze pytanie co do tego fragmentu. Czy jest poprawny? https://pastebin.com/raw/RnvBX5ju -
Przepraszam jeśli niejasno opisałem

1

for (i = 1; i <= n; ++i) // i = 0 przechowuje n,

Przechodzisz po elementach tablicy (ogólnie mówiąc), w której trzymasz jej własny rozmiar. Mnie się w głowie nie mieści taka konstrukcja. Nie jest niepoprawna pod względem składniowym, jak widać działa nawet, ale to pomieszanie z poplątaniem pod względem logicznym. Rozmiar tablicy powinien być przechowywany osobno, jeśli w ogóle (dynamiczne kolekcje są lepsze, jak vector, jeśli oczywiście można ich użyć).

To jest całkiem niepoprawne. Nie wyobrażam sobie sytuacji, w której to by się przydało. Ale nie programuję w C++, może to taki algorytm?

3

n - pierwszy element pliku który przechowuje ilosc danych w 2 wierszu

... i to aż prosi się o użycie std::vector, bo z tego wynika, że ilość danych jest ściśle zależna od ilości danch w plikach.

0

Może zapisać każdą z 4 linii pliku do osobnych std::vector ?

getline(plik,vector);

i tak 4 razy. Czy tak też można zrobić, aby w łatwiejszy sposób operować na danych niż zapisywać je wszystkie do jednego std::vector, bo chyba nie da się przenieść danych z jednego std::vector , kasując przy tym, do drugiego?

0

Za pomocą getline się tak nie da -- musi wczystywać ręcznie w pętli...

2
long long il, minc = 6500
int minc = 6500;

Tutaj jest zakrywanie zmiennej globalnej, deklaracją zmiennej lokalnej w funkcji main()
i własnie dlatego należy unikać zmiennych deklarowanych globalnie.

1

Jak myślisz, jaką wartość ma n?

  vector<int> numbers;
  int n = numbers[0];

Wczytujesz jakieś liczby z pliku po czym od razu jest nadpisujesz czymś innym(czym? tablica mas również nie jest zainicjalizowana). Na dodatek nie sprawdzasz czy n mieści się w numbers.size().

while (text >> integer)
	{
		numbers.push_back(integer);
		i++;
	}

	for (i = 1; i <= n; ++i)
	{
		numbers[i] = mas[i];
		minc = min(minc, mas[i]);
	}

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