Naruszenie dostępu do odczytu. x było 0x1110112 - Eliminacja Gaussa.

0

Hello!
Ktoś powie , gdzie w tym kodzie mam błąd , bo pisze mi : Zgłoszono wyjątek: naruszenie dostępu do odczytu.
x było 0x1110112.

double * gauss(double **a, double *y, int n)
{
	double *x, max;
	int k, index;
	const double eps = 0.00001;
	x = (double*)malloc(sizeof(double)* n);
	k = 0;
	while (k < n)
	{

		max = fabs(a[k][k]);
		index = k;
		for (int i = k + 1; i < n; i++)
		{
			if (fabs(a[i][k]) > max)
			{
				max = fabs(a[i][k]);
				index = i;
			}
		}

		if (max < eps)
		{
			printf("Zerowa kolumna - error ");
			printf("%d macierzy A\n", index);
			return 0;
		}
		for (int j = 0; j < n; j++)
		{
			double temp = a[k][j];
			a[k][j] = a[index][j];
			a[index][j] = temp;
		}
		double temp = y[k];
		y[k] = y[index];
		y[index] = temp;

		for (int i = k; i < n; i++)
		{
			double temp = a[i][k];
			if (fabs(temp) < eps) continue; 
			for (int j = 0; j < n; j++)
				a[i][j] = a[i][j] / temp;
			y[i] = y[i] / temp;
			if (i == k)  continue; 
			for (int j = 0; j < n; j++)
				a[i][j] = a[i][j] - a[k][j];
			y[i] = y[i] - y[k];
		}
		k++;
	}
	
	for (k = n - 1; k >= 0; k--)
	{
		x[k] = y[k];
		for (int i = 0; i < k; i++)
			y[i] = y[i] - a[i][k] * x[k];
	}
	return x;
}

int main()
{
	double **a, *y, *x;
	int n;
	system("chcp 1251");
	system("cls");
	printf("Wpisz ilosc rownan ");
	scanf("%d", &n);
	a = (double**)malloc(n * sizeof(double));

	y = (double*)malloc(sizeof(double)* n);
	x = (double*)malloc(sizeof(double)* n);

	for (int i = 0; i < n; i++)
	{
		a[i] = (double*)malloc(sizeof(double)* n);
		for (int j = 0; j < n; j++)
		{
			printf("a[%d][%d]= ", i, j);
			scanf("%d", &a[i][j]);
		}
	}
	for (int i = 0; i < n; i++)
	{

		printf("y[%d]= ", i);
		scanf("%d", &y[i]);

	}
	
	x=gauss(a, y, n);
	for (int i = 0; i < n; i++) {
		printf("x[%d]= %d", i, x[i]);
		printf("\n");
	}
	getchar();
	getchar();
	return 0;
}

Ten błąd wypisuje mi w tym miejscy (rozumiem , że problem jest w odnalezieniu tej tablicy, ale nie mam pojęcia gdzie mam źle):

printf("x[%d]= %d", i, x[i]);
3

Po pierwsze, to drukujesz double formatem integerowym. Na niektórych architekturach to oddzielne stosy argumentów bywały

Po drugie ustawiasz stronę kodową na Rosję i Ukrainę. Chyba za dużo wklejałeś bez analizy.

Moje niemłode już oczy się wyłączają jak widzą dwie gwiazdki. Ambitne algorytmy na wskaźnikach w C (w C++ można tego uniknąć) są bardzo subtelne. Na przykład nie bardzo jak masz zwrócić niepowodzenie, zwracasz 0 . Są czułe (co w małych szkolnych programach może nie być widać) na dealokację.

4
double **a, ...
 
a = (double**)malloc(n * sizeof(double));

Powinno być n * sizeof(double*)

4

Problem polega na tym, że masz za duże funkcje, więc trudno czytać ten kod.
Porównaj sobie to z tym: https://wandbox.org/permlink/ktsqg27KDrddnreY

Koledzy wyżej coś wypatrzyli, ale zapewne jest tego dużo więcej.

Polecam nauczyć się używać debuggera. IMO każdy początkujący powinien zacząć naukę od tego narzędzie (jeszcze przed napisaniem pierwszego "hello world"). Nauczysz się lokalizować błędy.

Możesz też spróbować użyć address sanitizer, który niedawno pojawił się w msvc (lata temu wprowadził go clang, a potem gcc). Pewnie pierwsze błędy, które ci będzie pokazywał, będą dla ciebie wyglądać jak chińszczyzna, ale jak się wczytasz to powinien pomóc.

3
AnyKtokolwiek napisał(a):

Na niektórych architekturach to oddzielne stosy argumentów bywały

Może rozwiniesz? Dla mnie to bełkot. nawet jak coś takiego jest, to jest to detal, który jest nieistotny, z punktu widzenia tego kodu.

AnyKtokolwiek napisał(a):

Po drugie ustawiasz stronę kodową na Rosję i Ukrainę. Chyba za dużo wklejałeś bez analizy.

Jest jeszcze gorzej. Nie powinien do tego używać system. Prawda jest taka, że to nic nie robi, a już an pewno nie ma wpływu na aplikację. Powinien użyć locale.
Zresztą nie ma powodu, by tego używać, (chyba, że dane maja przecinek jako separator dziesiętny).

To jest wskazówka, że najprawdopodobniej kod zerżnięty od innego początkującego.

0
MarekR22 napisał(a):
AnyKtokolwiek napisał(a):

Na niektórych architekturach to oddzielne stosy argumentów bywały

Może rozwiniesz? Dla mnie to bełkot. nawet jak coś takiego jest, to jest to detal, który jest nieistotny, z punktu widzenia tego kodu.

Pamiętam "romans" z systemach na Intelach 8086/186/286, NIE BĘDĄCYCH pecetami, w czasach jak asemblowanie się opłacało.
Dotykałem tego w tzw "OBR" kto wtedy działał, więc wie co to, za walizkę "dewiz z drugiego obszaru płatniczego"

Genialne od producenta sprzętu kompilatory C i Pascala, genialnie udokumentowane. I tam stos argumentów zmiennoprzecinkowych (80bitowych) był w oparciu o koprocesor.
Zaszłość, nie spotykałem współcześnie.

Masz rację, tu nieistotne wtrącenie.

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