Dynamiczna alokacja pamięci. Problem.

macmika
Użytkownik
Użytkownik
Posty: 14
Rejestracja: 13 gru 2010, o 23:53
Płeć: Mężczyzna
Lokalizacja: Wrocław

Dynamiczna alokacja pamięci. Problem.

Post autor: macmika »

Witam. Mam taki kod:

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

int main ()
{
  long int i,n,k,sum;
  long int * tab;

  printf ("Ile liczb? ");
  scanf ("%d", &i);

  tab = (long int*) malloc (i+1);
  if (tab==NULL) exit (1);

  for (n=0; n<i; n++)
  {
    tab[n]=10;
    sum=sum+tab[n];
}
  tab[i]='\0';
  printf("%d",sum); 
  free (tab);
  getch();
  return 0;

}
I teraz tu pojawia się problem. Program się kompiluje. Liczy cuś, ale zaraz potem wyskakuje okienko, że program przestał działać. Dodam, że nie jest to poprawny wynik. Mógłby mi ktoś dać jakąś wskazówke co jest nie tak. Byłbym bardzo wdzięczny. Pozdrawiam.
wawek91
Użytkownik
Użytkownik
Posty: 795
Rejestracja: 2 cze 2010, o 08:56
Płeć: Mężczyzna
Lokalizacja: Tarnów
Podziękował: 14 razy
Pomógł: 66 razy

Dynamiczna alokacja pamięci. Problem.

Post autor: wawek91 »

Jest już późno więc coś mogło mi sie pomieszać, ale skoro to nie jest tablica znakowa (char-ów) to czemu kończysz ją '\0'?
macmika
Użytkownik
Użytkownik
Posty: 14
Rejestracja: 13 gru 2010, o 23:53
Płeć: Mężczyzna
Lokalizacja: Wrocław

Dynamiczna alokacja pamięci. Problem.

Post autor: macmika »

Też na to po chwili wpadłem. Jednak usunięcie tego nic nie zmienia. Ale nieważne. Mam inne pytanie. Czy za pomocą operatora new możemy zadać z klawiatury rozmiar tablicy? Czy właśnie tylko funkcja malloc nam na to pozwala?
wszamol
Użytkownik
Użytkownik
Posty: 490
Rejestracja: 7 maja 2009, o 22:01
Płeć: Mężczyzna
Podziękował: 1 raz
Pomógł: 64 razy

Dynamiczna alokacja pamięci. Problem.

Post autor: wszamol »

Jeśli i to wielkość tablicy, a tab to wskaźnik na int, no to robisz:

Kod: Zaznacz cały

  long int i,n,k,sum;
  long int * tab;

  printf ("Ile liczb? ");
  scanf ("%d", &i);
  tab = new int [i];
macmika
Użytkownik
Użytkownik
Posty: 14
Rejestracja: 13 gru 2010, o 23:53
Płeć: Mężczyzna
Lokalizacja: Wrocław

Dynamiczna alokacja pamięci. Problem.

Post autor: macmika »

Ok tak zrobiłem. Jednak teraz pojawia się inny problem:

Kod: Zaznacz cały

#include <stdlib.h>
#include <conio.h>
#include <stdafx.h>
void tabl(int tab[], int *rozm, int z)
{	
	*rozm=*rozm+1;
	tab = new int [*rozm];
	tab[*rozm]=z;

}


int main ()
{
	int *tab;
	int rozm;
	int z,y;
	printf("Podaj rozmiar:
");
	scanf("%d",&rozm);
	tab = new int [rozm];
	for(int i=0;i<rozm;i++)
		tab[i]=10+i;
	for(int k=0;k<rozm;k++)
		printf("%d
",tab[k]);
  scanf("%d",&z);
  tabl(tab,&rozm,z);
  printf("------");
  for(int o=0;o<rozm;o++)
	  printf("%d",tab[o]);
delete [] tab;
  scanf("%d",&y);
  getchar();
  return 0;
}
Program się kompiluje. Przy pierwszym razie tablice wypisuje jak należy, jednak po wywołaniu funkcji i ponownym wypisaniu tab na ekranie pokazują się to co wcześniej + jakaś losowa liczba. Czyli po prostu źle wyświetla tą liczbe zadawaną z klawiatury, która ma być na ostatnim miejscu. Jakieś pomysły?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Dynamiczna alokacja pamięci. Problem.

Post autor: Afish »

Po pierwsze w funkcji tab1 masz wyciek pamięci. Po drugie wyjeżdżasz poza zakres tablicy.
macmika
Użytkownik
Użytkownik
Posty: 14
Rejestracja: 13 gru 2010, o 23:53
Płeć: Mężczyzna
Lokalizacja: Wrocław

Dynamiczna alokacja pamięci. Problem.

Post autor: macmika »

Kod: Zaznacz cały

#include <stdlib.h>
#include <conio.h>
#include <stdafx.h>
void tabl(int tab[], int *rozm, int z)
{   
   *rozm=*rozm+1;
   tab = new int [*rozm+1];
   tab[*rozm]=z;

}
Zmieniłem to dodając 1 co rozmiaru. Teraz program wyświetla prawidłowo nową tablice, jednak potem się wywala z komunikatem, że aplikacja zapisuje do pamięci przekraczającej zakres programu.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Dynamiczna alokacja pamięci. Problem.

Post autor: Afish »

Ciągle masz wyciek pamięci, bo wskaźnik jest przekazywany przez wartość, a nie przez zmienną.
macmika
Użytkownik
Użytkownik
Posty: 14
Rejestracja: 13 gru 2010, o 23:53
Płeć: Mężczyzna
Lokalizacja: Wrocław

Dynamiczna alokacja pamięci. Problem.

Post autor: macmika »

Nie rozumiem, mógłbyś mi dać jeszcze jakąś wskazówkę? Chodzi o przekazanie rozm do funkcji? Czy o parametr z? Dzięki.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Dynamiczna alokacja pamięci. Problem.

Post autor: Afish »

Do funkcji przekazujesz wskaźnik, ale przekazujesz go przez wartość. Czyli w funkcji tworzona jest lokalna kopia wskaźnika. Następnie do tego nowego wskaźnika alokujesz nową pamięć. Po wyjściu z funkcji nowy wskaźnik jest usuwany, ale świeżo zaalokowana pamięć zostaje. Tu jest wyciek. Ponadto w funkcj zwiększasz rozmiar (bo przekazujesz go przez zmienną), ale Twoja tablica z maina niestety się nie rozciąga.
macmika
Użytkownik
Użytkownik
Posty: 14
Rejestracja: 13 gru 2010, o 23:53
Płeć: Mężczyzna
Lokalizacja: Wrocław

Dynamiczna alokacja pamięci. Problem.

Post autor: macmika »

Czy mógłbyś mi pokazać jak to zrobić? Co to znaczy, że przekazuje wartość? Ale mówimy o parametrze z czy o rozm? Czy jeżeli w funkcji powiększyłbym po prostu stałą liczbą rozmiar tablicy to ona wróciłaby powiększona?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Dynamiczna alokacja pamięci. Problem.

Post autor: Afish »

Mówimy o parametrze tab. Spróbuj dokładnie wczytać się w to, co napisałem i zrozumieć, gdzie jest błąd. No i poza tym zauważ najprostszą rzecz - masz więcej new, niż delete. Tutaj masz przykładowy kod, który powinien działać tak, jak należy:
Ukryta treść:    
macmika
Użytkownik
Użytkownik
Posty: 14
Rejestracja: 13 gru 2010, o 23:53
Płeć: Mężczyzna
Lokalizacja: Wrocław

Dynamiczna alokacja pamięci. Problem.

Post autor: macmika »

Teraz jest dobrze, dzięki wielkie! Ale mam jeszcze pytanie. Dlaczego przekazując tab do funkcji musimy użyć wskaźnika? Przecież sama tablica jest wskaźnikiem na początek?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

Dynamiczna alokacja pamięci. Problem.

Post autor: Afish »

Bo przekazujesz wskaźnik przez wartość. A to oznacza, że funkcja owszem, ma wskaźnik, ale ma swoją własną kopię. I ta kopia jest absolutnie niezależna od tej wersji z maina. Co oznacza, że modyfikacja wskaźnika w funkcji tabl sprawia, że po zakończeniu funkcji wszelkie te zmiany są tracone. Stąd wyciek pamięci i śmieci na końcu tablicy.
ODPOWIEDZ