• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Błąd ze wskaźnikami. [ ZMORA ]

Object Storage Arubacloud
0 głosów
198 wizyt
pytanie zadane 14 stycznia 2016 w C i C++ przez Sebastian R Obywatel (1,110 p.)
edycja 14 stycznia 2016 przez Sebastian R

Mam do zrobienia programy na wskaźnikach, które w funkcji koniec - będą dodawały jedno pole na koniec tablicy.

funkcji wstaw  - dodaje we wskazany indeks tablicy i powieksza sie o jeden tablica.

funkcji poczatek - "usuwa" pierwszą liczbe z tablicy.

mam coś takiego, ale ciagle mi wyskakuje bład....

void poczatek(Punkt *tab,int &rozmiar)
{
    for (int i = 0; i < rozmiar - 1; i++)
    {
        tab[i].y = tab[i + 1].y;
        tab[i].x = tab[i + 1].x;
    }
    tab = (Punkt*)realloc(tab, rozmiar*sizeof(Punkt));
}
void koniec(Punkt *tab, int &rozmiar)
{
    printf("%d", rozmiar);
        tab = (Punkt*)(realloc(tab, (rozmiar)*sizeof(Punkt)));
}
void wstawiaj(Punkt *tab, int &x1, int &rozmiar)
{
    double wartosc1, wartosc2;
    rozmiar++;
    tab = (Punkt*)(realloc(tab, (rozmiar)*sizeof(Punkt)));
    printf("Jaka wartosc x%d: ", x1);
    scanf("%lf", &wartosc1);
    printf("Jaka wartosc y%d: ", x1);
    scanf("%lf", &wartosc2);
    for (int i = rozmiar - 1; i >= x1; i--)
    {
        tab[i].x = tab[i - 1].x;
        tab[i].y = tab[i - 1].y;
    }
    tab[x1].x = wartosc1;
    tab[x1].y = wartosc2;
}
case '5':
        {
            printf("ile dodać komorek na koniec tablicy?");
            scanf("%d", &j);
            rozmiar += j;
            koniec(tab, rozmiar);
            getchar();
            break;
        }
        case '6':
        {
            printf("\nzostanie usunieta pierwsza komorka.\n");
            rozmiar--;
            poczatek(tab, rozmiar);
            break;
        }
        case '0':
       
        {
 
        printf("Tablica:\n");
            for (int i = 0; i < rozmiar; i++)
            {
                printf("%d. X: %3.2f  ", i + 1, tab[i].x);
                printf(" Y: %3.2f\n", tab[i].y);
            }
        break;
        }
        case '7':
        {
            printf("\nNa jaka pozycje x i y?\n");
            scanf("%d", &x1);
            if (x1 > rozmiar)
            {
                printf("Nie chcesz chyba wyjsc poza tablice, prawda towarzyszu?");
            }
            else
            {
                wstawiaj(tab, x1, rozmiar);
            }
            break;
        }

 

3 odpowiedzi

0 głosów
odpowiedź 14 stycznia 2016 przez niezalogowany
A jaki to błąd??
0 głosów
odpowiedź 14 stycznia 2016 przez Patrycjerz Mędrzec (192,320 p.)

Nie wiem, czy jest to związane z błędem, ale w instrukcjach if zamiast == stosujesz =.

komentarz 14 stycznia 2016 przez Sebastian R Obywatel (1,110 p.)
poprawiłem - wrzucilem wczesniejszy kod, ten do którego odwołuje się moja laborantka. Ponadto ten if to był sprawdzeniem czy wskaznik otrzymuje jakąś wartość
0 głosów
odpowiedź 14 stycznia 2016 przez Sebastian R Obywatel (1,110 p.)
Uzasadnienie błędu mojej laborantki był następujący:

Proszę sobie doczytać jak działa relokacja pamięci. Dostaje Pan nowy wskaźnik. W 99% przypadków będzie miał taką samą wartość jak stary, dlatego Pana program "działa".

Nie mogę sobie tego uzmysłowić...
komentarz 14 stycznia 2016 przez mbabane Szeryf (79,280 p.)

może chodziło jej o to ze cały czas operujesz na oryginale i jakby funkcja realloc() źle zadziałała to mógłbyś stracić tablice!

http://4programmers.net/C/Biblioteka_standardowa/Stdlib.h/Realloc

komentarz 14 stycznia 2016 przez Sebastian R Obywatel (1,110 p.)

Teraz stworzyłem taką alokacje, ale coś nie pozwala mi powiekszyc kilkukrotnie wiekszy zakres, co jest źle?

void koniec(Punkt *tab, int &rozmiar,int &j)
{	
	void *wsk = NULL;
	wsk = (Punkt*)(realloc(tab, (rozmiar + j)*sizeof(Punkt)));
	if (wsk = NULL)
	{
		printf("blad alokacji");
	}
	else
	{
		tab = (Punkt*)wsk;
		rozmiar = rozmiar + j;
		printf("rozmiar to: %d", rozmiar);
	}
	free(wsk);
}  
void wstawiaj(Punkt tab[], int &x1, int &rozmiar)
{
	double wartosc1, wartosc2;
	void *wsk = NULL;
	wsk = (Punkt*)(realloc(tab, (rozmiar + 1)*sizeof(Punkt)));
	if (wsk == NULL)
	{
		printf("blad alokacji");
	}
	else
	{
		tab = (Punkt*)wsk;
		rozmiar = rozmiar + 1;
		printf("rozmiar to: %d", rozmiar);
		printf("\nJaka wartosc x%d: ", x1);
		scanf("%lf", &wartosc1);
		printf("\nJaka wartosc y%d: ", x1);
		scanf("%lf", &wartosc2);
		for (int i = rozmiar - 1; i >= x1; i--)
		{
			tab[i].x = tab[i - 1].x;
			tab[i].y = tab[i - 1].y;
		}
		tab[x1].x = wartosc1;
		tab[x1].y = wartosc2;
	}

}

 

komentarz 14 stycznia 2016 przez mbabane Szeryf (79,280 p.)

panie kolegeo   if (wsk = NULL)!!!!  jaki operator logiczny srpawdza rownosc?

 

free(wsk) wydaje mi sie ze powinno byc w else

komentarz 14 stycznia 2016 przez Sebastian R Obywatel (1,110 p.)

Tak, dokładnie tak. Poprawione, ale teraz program się wywala przy linijce:

    wsk = (Punkt*)(realloc(tab, (rozmiar+j)*sizeof(Punkt)));


pewnie z nią jest wszystko okej, ale z czymś innym może być problem. Wyślę cały kod programu.

// ConsoleApplication8.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>
#include <windows.h>
struct Punkt
{
	double x;
	double y;
	void *wsk;
};
void wypelnienielosowe(Punkt *tab, int &rozmiar)
{
	for (int i = 0; i <rozmiar; i++)
	{
		tab[i].x = rand() % 1001 / 100.;
		tab[i].y = rand() % 1001 / 100.;
	}
}
void wypelnienie(Punkt *tab, int &rozmiar)
{
	for (int i = 0; i < rozmiar; i++)
	{
		printf("Wpisz punkt X");
		scanf("%lf", &tab[i].x);
		printf("Wpisz punkt Y");
		scanf("%lf", &tab[i].y);
	}
}
double dwapunkty(Punkt *punkty)
{
	return pow((pow((punkty[0].x - punkty[1].x), 2) + pow((punkty[0].y - punkty[1].y), 2)), (1 / 2.));
}
void odleglosc(Punkt *tab, int &rozmiar)
{
	double wynik1 = 0, wynik2 = 0, pomoc = 0,k=1;
	while (k != 0)
	{
		k = 0;
		for (int i = 0; i < rozmiar-1; i++)
		{	
			wynik1 = pow(pow(tab[i].x, 2) + pow(tab[i].y, 2), 1 / 2.);
			wynik2 = pow(pow(tab[i + 1].x, 2) + pow(tab[i + 1].y, 2), 1 / 2.);
			if (wynik1 > wynik2)
			{
				pomoc = tab[i].x;
				tab[i].x = tab[i + 1].x;
				tab[i + 1].x = pomoc;
				pomoc = tab[i].y;
				tab[i].y = tab[i + 1].y;
				tab[i + 1].y = pomoc;
				k++;
			}
		}
	}
}
void poczatek(Punkt tab[],int &rozmiar)
{
	void *wsk = NULL;
	wsk = (Punkt*)(realloc(tab, (rozmiar + 1)*sizeof(Punkt)));
	for (int i = 0; i < rozmiar - 1; i++)
	{
		tab[i].y = tab[i + 1].y;
		tab[i].x = tab[i + 1].x;
	}

	if (wsk = NULL)

	{
		printf("blad alokacji");
		free(tab);
	}
	else
	{
		tab = (Punkt*)&wsk;
		rozmiar = rozmiar - 1;
		printf("rozmiar to: %d", rozmiar);

	}
	free(wsk);
}
void koniec(Punkt tab[], int &rozmiar,int &j)
{	
	void *wsk = NULL;
	wsk = (Punkt*)(realloc(tab, (rozmiar+j)*sizeof(Punkt)));
	if (wsk == NULL)
	{
		printf("blad alokacji");
		free(tab);
		free(wsk);
	}
	else
	{
		tab = (Punkt*)wsk;
		rozmiar = rozmiar + j;
		printf("rozmiar to: %d", rozmiar);
		
	}
	
}  
void wstawiaj(Punkt* tab, int &x1, int &rozmiar)
{
	double wartosc1, wartosc2;
	void *wsk;
	wsk = (Punkt*)(realloc(tab, (rozmiar + 1)*sizeof(Punkt)));
	if (wsk == NULL)
	{
		printf("blad alokacji");
		
	}
	else
	{
		tab = (Punkt*)&wsk;
		rozmiar = rozmiar + 1;
		printf("rozmiar to: %d", rozmiar);
		printf("\nJaka wartosc x%d: ", x1);
		scanf("%lf", &wartosc1);
		printf("\nJaka wartosc y%d: ", x1);
		scanf("%lf", &wartosc2);
		for (int i = rozmiar - 1; i >= x1; i--)
		{
			tab[i].x = tab[i - 1].x;
			tab[i].y = tab[i - 1].y;
		}
		tab[x1].x = wartosc1;
		tab[x1].y = wartosc2;
	}
	free(wsk);

}
int main()
{
	srand(time(NULL));

	int  rozmiar=0, j=0,x1=0,petla=1;
	char wybor;
	Punkt *tab=NULL;
	Punkt *punkty=NULL;

	

	printf("wpiszcie tutaj rozmiar tablicy: ");
	scanf("%d", &rozmiar);
	
	(Punkt*)tab = (Punkt*)calloc(rozmiar, sizeof(Punkt));
	if (tab == NULL)
	{
		printf("blad alokowania pamieci an poczatek!!!");
	}
	punkty = (Punkt*)calloc(2, sizeof(Punkt));

	while (true)
	{

	printf("1.Wybor losowy\n2.Wpisuj sam kazda komorke.\n");
	printf("3.f. zwraca odległość między zadanymi jako argumenty dwoma punktami\n4.f. sortuje zadaną jako argument tablicę wg odległości punktów od punktu(0.0)\n5.Dodaj komórke do tablicy na koncu.\n6.Funkcja usuwa pierwszy element.\n7.Funkcja dodaje na zadaną pozycje element.\n0. Wyswietl tablice.\n");
	
	wybor = _getch();


		switch (wybor)
		{
		case '1':
		{
			wypelnienielosowe(tab, rozmiar);
			printf("wszystko zostalo polosowane.\n");
			break;
		}
		case '2':
		{
			wypelnienie(tab, rozmiar);
			printf("wszystko zostalo polosowane.\n");
			break;
		}
		case '3':
		{
			for (int i = 0; i < 2; i++)
			{
				printf("Wpisz wartosc punktu X%d:", i + 1);
				scanf("%lf", &punkty[i].x);
				printf("Wpisz wartosc punktu Y%d:", i + 1);
				scanf("%lf", &punkty[i].y);
			}
			printf("Wynik to: %f", dwapunkty(punkty));
			break;
		}
		case '4':
		{
			odleglosc(tab, rozmiar);
			break;

		}
		case '5':
		{
			printf("ile dodać komorek na koniec tablicy?");
			scanf("%d", &j);
			koniec(tab, rozmiar,j);
			getchar();
			break;
		}
		case '6':
		{
			printf("\nzostanie usunieta pierwsza komorka.\n");
			poczatek(tab, rozmiar);
			break;
		}
		case '0': 
		
		{

		printf("Tablica:\n");
			for (int i = 0; i < rozmiar; i++)
			{
				printf("%d. X: %3.2f  ", i , tab[i].x);
				printf(" Y: %3.2f\n", tab[i].y);
			}
		break;
		}
		case '7':
		{
			printf("\nNa jaka pozycje x i y?\n"); 
			scanf("%d", &x1);
			if (x1 > rozmiar)
			{
				printf("Nie chcesz chyba wyjsc poza tablice, prawda towarzyszu?");
			}
			else
			{
				wstawiaj(tab, x1, rozmiar);
			}
			break;
		}
		}
		printf("\n\n\nProgram wykona okrazenie numer: %d", petla);
		Sleep(2000);
		system("cls");
		petla++;



	}
	getchar();
	free(tab);
	free(punkty);
    return 0;
}

 

Ten problem jest bardzo demotywujący.

 

komentarz 15 stycznia 2016 przez mbabane Szeryf (79,280 p.)

wydaje mi sie ze lepiej bedzie tutaj:
 (Punkt*)tab = (Punkt*)calloc(rozmiar, sizeof(Punkt));
zastosować funkcję malloc() 

Napisz jakie zadanie ma wsk w strukturze Punkt.

Deklarujac strukture w mainie powinno sie pisać za kazdym razem (a takze np. w funkcji sizeof() ):
struct nazwa_struktury zmienna
sizeof(struct nazwa_struktury)

a jesli nie chce nam sie tyle pisać, to wczesniej przed mainem trzeba dac:
typedef struct nazwa_struktury nowa_nazwa_zeby_nie_pisac_za_kazdym_razem_struct

 

w funkcji poczatek() znowu spierdzielony operator w ifie.

Dobra narazie tyle, jutro jeszcze na to popatrze, powodzenia!

Podobne pytania

0 głosów
2 odpowiedzi 378 wizyt
0 głosów
1 odpowiedź 499 wizyt
pytanie zadane 4 kwietnia 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)
0 głosów
1 odpowiedź 656 wizyt
pytanie zadane 1 kwietnia 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)

92,573 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...