prosty program, dlaczego nie działa jak powinien?

0

Hej,
Właściwie kilka dni temu rozpocząłem przygodę z programowaniem i już mam problem, dlaczego program nie działa jak powinien. Założenie jest takie, że program losuje dwuwymiarową tablicę znaków wypełnioną ' ' i 'X' przy czym spacji jest dwa razy wiecej, a rozmiar tablicy podawany jest przy uruchomieniu. Program potem powinien wyświetlać wylosowaną tablicę (ma to wyglądać jak taki labirynt) i w górnym roku ustawiać jedynkę. Następnie za pomocą klawiszy a,s,w,d możemy poruszać jedynką o ile poruszamy się po polach ze spacją (program nie reaguje jak chcemy wejść na X-ściany labiryntu).
I wszystko działa pięknie i fajnie, tylko jeśli wchodzę na pole ze spacją na lewym krańcu labiryntu, to jedynka przeskakuje mi na prawą stronę(o ile tam też jest spacja) i kontunuować spacer od drugiej storny. Moje pytanie dlaczego? Program nie powiniem reagować wtedy, bo kończy się tablica.

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <cstdlib>

using namespace std;


int main() {
	int pozycja1=0;
	int pozycja2=0;
	char gracz='1';
	char wybor='\0';
	int size=0;
	cout<<"podaj rozmiar planszy: ";
	cin >> size;
	char plansza[size][size]={'\0'};
	for(int i=0;i<=size;++i){
		for(int j=0;j<=size;++j){
			int liczba=rand()%3;
			if(liczba==0){
				plansza[i][j]='X';
			}
			else{plansza[i][j]=' ';}
			}
			}
			
		
	
	
	
	for(;;){
		system("cls");
		plansza[pozycja1][pozycja2]=gracz;
		
			for(int i=0;i<=size;++i){
		for(int j=0;j<=size;++j){
			cout<<plansza[i][j];
			}
			cout<<endl;
			}
		
		wybor=getch();
		switch(wybor){
			case 's':
				if(plansza[pozycja1+1][pozycja2]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja1=++pozycja1;
				}
				break;
			case 'w':
				if(plansza[pozycja1-1][pozycja2]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja1=--pozycja1;
				}
				break;
			case 'd':
				if(plansza[pozycja1][pozycja2+1]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja2=++pozycja2;
				}
				break;
			case 'a':
				if(plansza[pozycja1][pozycja2-1]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja2=--pozycja2;
				}
				break;
			default:
				break;
		}
		
	}
	
	return 0;
}
2

W pamięci komputera tablice

char tab1[4] = {'a', 'b', 'c', 'd'};
char tab2[2][2] = {{'a', 'b'}, {'c', 'd'}};

będą wyglądały identycznie.
tab2[0][2] to (w tym przypadku) to samo co tab2[1][0].
Sam język (C/C++) nie sprawdza czy doszedł do końca tablicy. To sprawdzenie należy do programisty.

2

Klasyczne Undefined Behavior (UB).
W C i C++ nie ma kontroli wykraczania poza zakres tablicy (ani w run time, ani podczas kompilacji).
A jak się już zdarzy, to może się stać cokolwiek (stąd pojęcie UB).

Tak jak napisał @Delor w tym wypadku trafiasz na komórkę z sąsiedniego wiersza. Jednak zależnie od kompilatora i jego ustawień, może stać się coś innego (np wielkość tablicy może być wyrównywana do paragrafu, wtedy wykroczenie poza zakres tablicy może trafić na nieużywany fragment pamięci).

Zwrócę jeszcze uwagę variable-length array (VLA) jest niestandardowe dla C++. Kompilatory domyślnie to przepuszczają, by zapewnić kompatybilność z C, gdzie VLA są dostępne.

0

wprowadzenie warunku na nie przekraczanie rozmiaru tablicy nic nie zmienia. Zmieniłem to co pod switchem na coś takiego:

	switch(wybor){
			case 's':
			   if(pozycja1+1<size){
			   
				if(plansza[pozycja1+1][pozycja2]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja1=++pozycja1;
				}}
				break;
			case 'w':
				if(pozycja1-1>=0){
				if(plansza[pozycja1-1][pozycja2]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja1=--pozycja1;
				}}
				break;
			case 'd':
				if(pozycja2+1<size){
				if(plansza[pozycja1][pozycja2+1]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja2=++pozycja2;
				}}
				break;
			case 'a':
				if(pozycja2-1>=0){
				if(plansza[pozycja1][pozycja2-1]==' '){
					plansza[pozycja1][pozycja2]=' ';
					pozycja2=--pozycja2;
				}}
				break;
			default:
				break;
		}
		
	}
1

Wychodzisz poza tablice. for(int i = 0; i <= size; ++i) => powinno być i < size. Identycznie dla j.

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