Błąd naruszenia dostępu do zapisu. Funkcja wczytująca sinusa + zaszumienie losowymi wartościami.

0

Witam! Moim zadaniem jest napisanie programu wczytującego funkcję sinusa jedno połówkowego oraz jego współczynników takich jak np. amplituda, a następnie w określonej dziedzinie zaszumienie losowych wartości sygnału sinusoidalnego losowymi wartościami. Wszystko jest okej, programik się kompiluje, ale po wpisaniu wszystkich potrzebnych danych pojawia się taki oto błąd:

(kod programu poniżej)

Zgłoszono wyjątek: naruszenie dostępu do zapisu.
tablica_wynikowa było 0x1100000

#define _CRT_SECURE_NO_WARNINGS				//sin jednopołówkowy
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<locale.h>


void wczytanie_rozmiaru(int rozmiar);
void dziedzina(double* poczatek_dz, double* koniec_dz);
void parametry_wejsciowe(double* tab_wspolczynnikow);	
void wartosci_funkcji_od_parametrow(double* tab_wspolczynnikow, double* tablica_wynikowa, double* poczatek_dz, double* koniec_dz, int rozmiar);
void wypisz_wartosci(double* tablica_wynikowa, int rozmiar);
void szumy(double* tab_szumy, double* poczatek_dz, double* koniec_dz);
//void filtr_sredniej(double* tab_szumy, double* tab_odfiltrowana, int rozmiar);
//void filtr_medianowy(double* tab_szumy, double* tab_odfiltrowana, int rozmiar);
//void CSV_zapis(double* tablica_wynikowa, double* tab_szumy, double* tab_odfiltrowana, int rozmiar);

int main()
{
	srand(time(NULL));
	setlocale(LC_ALL, "polish_poland");

	int rozmiar;
	wczytanie_rozmiaru(&rozmiar);

	double poczatek_dz;
	double koniec_dz;
	dziedzina(&poczatek_dz, &koniec_dz);

	double* tab_wspolczynnikow;
	tab_wspolczynnikow = calloc(rozmiar, sizeof(double));
	parametry_wejsciowe(tab_wspolczynnikow);

	double* tablica_wynikowa;
	tablica_wynikowa = calloc(rozmiar, sizeof(double));	

	double* tab_szumy;
	tab_szumy = calloc(rozmiar, sizeof(double));	


	wartosci_funkcji_od_parametrow(tab_wspolczynnikow, &tablica_wynikowa, &poczatek_dz, &koniec_dz, &rozmiar);
	wypisz_wartosci(&tablica_wynikowa, rozmiar);
	szumy(&tab_szumy, &poczatek_dz, &koniec_dz);

	return 0;
}
void wczytanie_rozmiaru(int* rozmiar)
{
	int temprozmiar;
	printf("Podaj rozmiar tablicy wynikowej:\n");
	scanf("%d", &temprozmiar);
	*rozmiar = temprozmiar;
}

void dziedzina(double* poczatek_dz, double* koniec_dz)
{
	do
	{
		printf("Podaj wartosc poczatku dziedziny:\n");
		scanf("%lf", poczatek_dz);
		printf("Podaj wartosc konca dziedziny:\n");
		scanf("%lf", koniec_dz);
		if (*poczatek_dz > *koniec_dz)
		{
			printf("Koniec dziedziny musi byc wiekszy niz poczatek! Sprobuj jeszcze raz!\n");
		}
	} while (*poczatek_dz > *koniec_dz);
}

void parametry_wejsciowe(double* tab_wspolczynnikow)  //parametry funkcji zapisane w tablicy
{
	printf("Podaj wartosc amplitudy:\n");
	scanf("%lf", &tab_wspolczynnikow[0]);
	printf("Podaj wartosc przesunieca fazowego (w osi x):\n");
	scanf("%lf", &tab_wspolczynnikow[1]);
	printf("Podaj wartosc przesuniecia po osi y (osi wartosci):\n");
	scanf("%lf", &tab_wspolczynnikow[2]);
}

void wartosci_funkcji_od_parametrow(double* tab_wspolczynnikow, double* tablica_wynikowa, double* poczatek_dz, double* koniec_dz, int rozmiar) //*tablica_wynikowa - tablica wyników po zastosowaniu parametrow
{
	int i;
	double zakres_dz;
	zakres_dz = fabs(koniec_dz - poczatek_dz); //fabs - dla liczb rzeczywistych

	for (i = 0; i < rozmiar; i++)
	{

		if (tab_wspolczynnikow[0] * (sin(*poczatek_dz + tab_wspolczynnikow[1])) + tab_wspolczynnikow[2] < 0)
		{
			*tablica_wynikowa++ = 0;
		}
		else
		{
			*tablica_wynikowa++ = tab_wspolczynnikow[0] * (sin(*poczatek_dz + tab_wspolczynnikow[1]) + tab_wspolczynnikow[2]);
		}

		*poczatek_dz = *poczatek_dz + (zakres_dz / rozmiar); 
	}

}

void wypisz_wartosci(double* tablica_wynikowa, int rozmiar)
{
	int i;
	for (i = 0; i < rozmiar; i++)
	{
		printf("%d wartosc z dziedziny wynosi : %lf\n", i,  tablica_wynikowa[i]);
	}
}

void szumy(double* tab_szumy, double* poczatek_dz, double* koniec_dz)
{
	double zaszumic_czy_nie;
	int j;
	double poczatek_szumu;
	double koniec_szumu;

	int b = (int)*poczatek_dz;									
	int c = (int)*koniec_dz;

	poczatek_szumu = *poczatek_dz + rand() % (c - b + 1);

	do
	{
		koniec_szumu = *poczatek_dz + rand() % (c - b + 1);
	} while (poczatek_szumu >= koniec_szumu);

	for (j = poczatek_szumu; j <= koniec_szumu; j++)
	{
		zaszumic_czy_nie = rand() % 2;
		if (zaszumic_czy_nie == 1)
		{
			tab_szumy[j] = rand() % 100 + 10;
		}
		printf("Wartosc %d po zaszumieniu - %lf\n", j, tab_szumy[j]);
	}
}

Nie bardzo wiem jak sobie w tym poradzić. Będę wdzięczny za każdą, nawet drobną pomoc.
Z góry dzięki!
HypheN

1

for (j = poczatek_szumu; j <= koniec_szumu; j++)

To jest bardzo ciekawa konstrukcja. Skąd wiesz że te indeksy mieszczą się między 0 a rozmiarem tablicy? A już szczególnie jak to jest w ogóle double jakieś, pewnie pewnie coś się zaokrągli, przytnie i nagle twoje j zaczyna się robić dziwne.

Proponuje odpalić debuger, ale możesz też wypisać sobie wartość j w tej pętli i upewnić się że jest ok.

0

Dodam tylko że błąd wywala mi dokładnie w przy sprawdzaniu tego else'a w funckji wartosci_funkcji_od_parametrow:

else
		{
			*tablica_wynikowa++ = tab_wspolczynnikow[0] * (sin(*poczatek_dz + tab_wspolczynnikow[1]) + tab_wspolczynnikow[2]);
		}

		*poczatek_dz = *poczatek_dz + (zakres_dz / rozmiar);
0

W sumie czemu alokujesz rozmiar tych współczynników, skoro wczytujesz i używasz 3? Jeszcze powiedz że w testach podajesz rozmiar 1 albo 2 ;]

1

Pisane z palca:

void szumy(double* tab_szumy,double poczatek_dz,double koniec_dz,int rozmiar)
{
    int j,start,stop;
    double poczatek_szumu,koniec_szumu,tmp,rozmiar_dziedziny=koniec_dz-poczatek_dz;

    poczatek_szumu=rozmiar_dziedziny*rand()/RAND_MAX;
    koniec_szumu=rozmiar_dziedziny*rand()/RAND_MAX;
    start=(int)round((rozmiar-1)*poczatek_szumu/rozmiar_dziedziny);
    stop=(int)round((rozmiar-1)*koniec_szumu/rozmiar_dziedziny);
    for (j=start;j<=stop;++j) if (rand()&1) tab_szumy[j] = 100.0*rand()/RAND_MAX-50;
    for (j=start;j<=stop;++j) printf("Indeks %d wartosc dziedziny %lf wartosc szumu: %lf\n",j,poczatek_dz+j*rozmiar_dziedziny/(rozmiar-1),tab_szumy[j]);
}

Zrób sobie kilka funkcji pomocniczych:

double inputDouble(const char *msg)
{
	double value;
	printf("%s: ",msg);
	scanf("%lf",&value);
	return value;
}
unsigned inputUnsigned(const char *msg) // dla rozmairu tablicy
{
	unsigned value;
	printf("%s: ",msg);
	scanf("%u",&value);
	return value;
}

Oraz strukturę na wszystko, do funkcji przekazujesz tylko adres struktury:

typedef struct 
{
	double *tablica_wynikowa,*tab_szumy,tab_wspolczynnikow[3]; // zamiast tab_wspolczynnikow[3] może lepiej wspA,wspB,wspC ?
	double poczatek_dz,koniec_dz;
	unsigned rozmiar;
} Dane;

Po takich udogodnieniach:

void dziedzina(Dane *dane)
{
	double tmp;
	dane->poczatek_dz=inputDouble("Podaj wartosc poczatku dziedziny");
	dane->koniec_dz=inputDouble("Podaj wartosc konca dziedziny");
	if(dane->poczatek_dz>dane->koniec_dz)
	{
		tmp=dane->poczatek_dz;
		dane->poczatek_dz=dane->koniec_dz;
		dane->koniec_dz=tmp;
	}
}

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