C Zapisywanie tablicy dynamicznej

0

Witam
Mam problem przy wpisywaniu liczb do tablicy dynamicznej. Zaalokowałem potrzebną ilość miejsca w osobnej funkcji w ten sposób:

[...] *Adres = (int*) malloc(*Rozmiar * sizeof(int)); [...]

i ta cała funkcja jest na pewno poprawna. Gdy jednak w innej funkcji chcę wpisać do tej tablicy liczby podawane przez użytkownika, po wpisaniu drugiej liczby wyskakuje błąd ochrony pamięci. Robię to w ten sposób

 for(a; a<*Rozmiar-1; a++)
{
    printf("Podaj kolejne liczby\n");
    scanf("%i", Adres[a]);
    printf("Zapisalem %i", *Adres[a]);
}

Adres i rozmiar tablicy jest też poprawnie przekazany do funkcji która ma w nią wpisywać dane.
Gdzieś tu jest banalny błąd którego nie widzę i nie mogę się domyślić co tu nie gra :)
Sprawdzałem także adresy komórek pamięci do których chciałem wpisać liczby (printf("%i", &Adres[a])) i zgadzały się one z tymi zaalokowanymi w poprzedniej funkcji. Czyżby jakiś głupi błąd w konstrukcji pętli for?

Jeśli będzie potrzeba mogę wkleić cały kod i objaśnić dokładniej na czym ma polegać program, ale generalnie chodzi mi o to jak poprawnie zapisać dynamiczną tablicę jednowymiarową. Wydawało mi się że to ma być tak jak zrobiłem, ale najwyraźniej się mylę :)
Z góry dzięki za pomoc
Pozdrawiam

0

Proponuje wkleic caly kod

0

Ok, wklejam zatem to co udało mi się napisać. Program nie jest skończony przez problem który się pojawił. Brakuje jeszcze 2 funkcji - sortowania i wypisywania, ale tym się zajmę jak rozwiąże problem :) Główne zadanie jest takie - użytkownik podaje ilość liczb które wprowadzi, następnie podaje różne liczby, program je wczytuje do tablicy dynamicznej, sortuje rosnąco i wypisuje na standardowym wyjściu. Tak jak wspomniałem, po podaniu drugiej liczby wyskakuje błąd ochrony pamięci.
Kodzik

#include <malloc.h>
#include <stdio.h>
const int  MaksRozmTablicy = 50;

int UtworzTabliceWgWskazanUzytkownika( int *wRozmiarTab,  int **wTabLiczb )
{
  printf("\nWprowadz ilosc liczb calkowitych, ktore nalezy wczytac:\n");
  scanf("%d",wRozmiarTab);
  while (*wRozmiarTab <= 0 || *wRozmiarTab > MaksRozmTablicy) {
    printf("\nWprowadziles niepoprawna wartosc.\n");     
    printf("Ilosc liczb musi byc wieksza od 0 i mniejsza od 51.\n\n");
    printf("Wprowadz ilosc liczb calkowitych, ktore nalezy wczytac:\n");
    scanf("%d",wRozmiarTab);
  }
  *wTabLiczb = (int*) malloc(*wRozmiarTab * sizeof(int));
  return wTabLiczb ? 0 : -1;
}
int Wczytaj(int *Rozmiar, int **Adres)
{
int a=0;
for(a; a<*Rozmiar-1; a++)
{
	printf("Podaj kolejne liczby\n");
  scanf("%i", Adres[a]);
 printf("Zapisalem %i", *Adres[a]);
}
a=0;
printf("w tablicy mamy kolejno ");
for(a; a<*Rozmiar-1; a++)
	{
		printf("%i ", *Adres[a]);
	}
return 0;
}
int main()
{
  int IloscLiczb;
  int *TabLiczb = NULL;
  if (UtworzTabliceWgWskazanUzytkownika(&IloscLiczb, &TabLiczb) != 0) {
    fprintf(stderr,":( Brak pamieci. Tablica liczb nie zostala utworzona\n");
    return 1;
  }

Wczytaj(&IloscLiczb, &TabLiczb);
  free(TabLiczb);
  return 0;
}
0
int Wczytaj(int *Rozmiar, int **Adres)

Rozmiar nie powinien byc wskaznikiem - tzn. teoretycznie moglby byc ale nie ma to sensu, wiec zostaw typ prosty. Podobnie z parametrem adres - podwojny wskaznik mogl Ci sie przydac w funkcji "UtworzTabliceWgWskazanUzytkownika" - po zarezerwowaniu pamieci nie jest Ci juz potrzebny. Proponuje wiec:

int Wczytaj(int Rozmiar, int *Adres)

Dalej:

for(a; a<*Rozmiar-1; a++)

Powinno byc:

for(a; a < Rozmiar; a++)

Powyzszy przypadek dotyczy obu petli zawartych w fukncji "Wczytaj". Pozniej to:

scanf("%i", Adres[a]);

Zamienisz na:

scanf("%i", &Adres[a]);

A to:

printf("Zapisalem %i", *Adres[a]);

Zamienisz na:

printf("Zapisalem %i", Adres[a]);

Ostatecznie:

int Wczytaj(int Rozmiar, int *Adres) {
    int a = 0;
    for (a; a < Rozmiar; a++) {
        printf("Podaj kolejne liczby\n");
        scanf("%i", &Adres[a]);
        printf("Zapisalem %i", Adres[a]);
    }
    a = 0;
    printf("w tablicy mamy kolejno ");
    for (a; a <Rozmiar; a++) {
        printf("%i ", Adres[a]);
    }
    return 0;
}

I wywolanie:

Wczytaj(IloscLiczb, TabLiczb);

Powinno dzialac. Pisalem troche na szybko

0

Chwali się próba logicznego podzielenia programu na funkcje. Jeszcze brakuje ci zmysłu co powinno się znaleźć w osobnej funkcji, ale to przyjdzie z czasem (mieszasz logikę z operacjami IO).

Problem wynika ze złego użycia wskaźników. W kodzie masz argument int **Adres i teraz jak go używasz jako Adres[a] to dostajesz zły adres, ty chcesz coś takiego (*Adres)+a a swoim zapisem uzyskałeś coś takiego *(Adres+a). Mam nadzieję że widzisz i zrozumiesz różnicę.
Popraw tak:

int Wczytaj(int Rozmiar, int *Adres)
{
    int a;
    for(a=0; a<Rozmiar; a++) {
        printf("Podaj kolejne liczby\n");
        scanf("%d", &Adres[a]);
    }
    printf("w tablicy mamy kolejno ");
    for(a=0; a<Rozmiar; a++) {
        printf("%d ", Adres[a]);
    }
    return 0;
}
0

Wielkie dzięki Panowie, naprawiłem błąd, dopisałem resztę, program już działa, bez Was by mi się nie udało. Przeanalizowałem wszystko jeszcze raz i już wiem gdzie popsułem sprawę. Co do sposobu podziału na funkcje który nie podoba Ci się MarekR22, otóż sposób ten jest odgórnie wyznaczony przez prowadzącego (jestem studentem) i w treści zadania było wyraźnie zaznaczone na jakie funkcje należy podzielić program i co ma się w nich znaleźć :) Nie wnikałem czy jest to logiczne czy nie, po prostu trzymałem się wytycznych i nawet nie zastanawiałem się nad innym rozwiązaniem :)
Jeszcze raz dziękuję za pomoc
Pozdrawiam

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