[SOLVED][c++] Własna dynamiczna tablica

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Awatar użytkownika
pixelenter
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 194
Rejestracja: 31 gru 2009, 15:41
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86_64

[SOLVED][c++] Własna dynamiczna tablica

Post autor: pixelenter »

Oczywiście wiem o operatorach new i delete. Problem mam tylko z rozszerzaniem tablic. Kod

Kod: Zaznacz cały

void addINT(int *INT, int add, int *Objects)
{
	int* objectID = new int[Objects++];
	for(int i=0; i<Objects-1; i++)
	{
		objectID[i] = INT[i];
	}
	objectID[Objects-1]=add;
	
	INT=objectID;
}
W "Obiects" znajduje się liczba obiektów. Biblioteka z tą funkcją ma być dostępna zarówno dla c++ jak i dla c. Na razie mam jeden problem:craz:. Po użyciu funkcji np. w ten sposób:

Kod: Zaznacz cały

addINT(i,12,Objects_i)
Wyskakuje mi jakaś dziwna liczba:wall:. Niby działa, no ale nie działa. Problem za pewne prosty jak drut, ale nie wiem czemu nie mogę sobie z nim poradzić. Proszę o szybką pomoc
http://uwolnijlaptopa.pl
http://counter.li.org/cgi-bin/certificate.cgi/528644
kklimonda
Zakręcona Traszka
Zakręcona Traszka
Posty: 585
Rejestracja: 20 kwie 2008, 04:21
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME

Odp: [c++] Własna dynamiczna tablica

Post autor: kklimonda »

Ta twoja funkcja nawet się nie skompiluje - przeklej tu cały, działający program albo jeszcze lepiej odpal całość w debuggerze i poszukaj błędu samemu. Więcej zrozumiesz niż jak gdyby ktoś ci wytłumaczył.

PS Swoją drogą ta funkcja będzie strasznie niewygodna do użycia, podawanie za każdym razem ilości obecnych elementów szybko się znudzi.
Awatar użytkownika
JoeBuck
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 125
Rejestracja: 07 lip 2009, 12:06
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [c++] Własna dynamiczna tablica

Post autor: JoeBuck »

Nie wiem, czy to to wywołuje Twój problem, ale chciałbym zwrócić uwagę, że w czasie wykonywania tej funkcji rozmiar tablicy INT nie zmienia się, a dokładasz do niej dodatkowy element... możesz w ten sposób naruszyć pamięć np. innej zmiennej...

P.S. Co rozumiesz przez "Biblioteka z tą funkcją ma być dostępna zarówno dla c++ jak i dla c"?
http://www.kotwburaczkach.pl
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Odp: [c++] Własna dynamiczna tablica

Post autor: ethanak »

JoeBuck pisze:P.S. Co rozumiesz przez "Biblioteka z tą funkcją ma być dostępna zarówno dla c++ jak i dla c"?
Jak mniemam cos w stylu:
Co najmniej jednego z tych dwóch języków nie znam (szczególnie tego z jedna literką)
Кто жопой родился, чижиком не помрёт
Awatar użytkownika
dawwin
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 202
Rejestracja: 18 kwie 2009, 09:16
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [c++] Własna dynamiczna tablica

Post autor: dawwin »

Po pierwsze
'Objects' jest wskaźnikiem, więc powinieneś zrobić coś takiego

Kod: Zaznacz cały

(*Objects)++;
int* objectID = new int[*Objects];
Czyli użyć operatora wyłuskania (*) konsekwentnie we wszystkich miejscach, gdzie używasz zmiennej
Po drugie jeśli chcesz zwrócić ObjectID przez wskaźnik to powinieneś użyć wskaźnika na wskaźnik, gdyż

Kod: Zaznacz cały

INT=objectID;
Nadpisze tylko lokaną kopię wskaźnika
Po trzecie powinieneś zwolnić starą tablicę

EDYCJA:
Po czwarte warto sprawdzić, czy pamięc została ci przydzielona.

Kod: Zaznacz cały

if (objectID == NULL) {
//jakies operacje
}
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
DDAroo
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 107
Rejestracja: 27 cze 2009, 10:47
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: KDE Plasma
Architektura: x86
Lokalizacja: Kraków
Kontakt:

Odp: [c++] Własna dynamiczna tablica

Post autor: DDAroo »

To ja jeszcze tylko dorzucę, że zamiast pętli lepiej skopiować jednocześnie wszystkie stare elementy za pomocą funkcji memcpy, a jeśli zamierzasz często wywoływać swoją funkcję to lepiej użyć listy zamiast tablicy, żeby w kółko nie kopiować starych elementów.
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: [c++] Własna dynamiczna tablica

Post autor: luzakwielki »

DDAroo pisze:To ja jeszcze tylko dorzucę, że zamiast pętli lepiej skopiować jednocześnie wszystkie stare elementy za pomocą funkcji memcpy, a jeśli zamierzasz często wywoływać swoją funkcję to lepiej użyć listy zamiast tablicy, żeby w kółko nie kopiować starych elementów.
Jeśli chcesz korzystać z memcpy z C to lepiej użyć po prostu realloc (wtedy będzie automatycznie zmieniał rozmiar i kopiował (o ile potrzeba - przeważnie nie będzie kopiował)).
Listy (listy są alternatywą dla własnej implementacji list i nie nadają się do wszystkiego - czasami lepiej użyć tablicy/wektora. czasami listy innym razem kolejki...) jako alternatywa dla tablicy to strasznie zły pomysł (nie masz łatwego dostępu do n'tego elementu). Alternatywą są wektory (std::vector) i będą się zachowywać tak jak realokowana tablica.
pixelenter pisze:Biblioteka z tą funkcją ma być dostępna zarówno dla c++ jak i dla c.
Jako skompilowana biblioteka za pomocą kompilatora c++, może i będzie działać z C, ale nie skompilujesz jej za pomocą kompilatora C (w języku C nie masz new i delete, ale masz dużo fajniejsze imo malloc, calloc, realloc, free (no fajniejsze poza tym, że nie wywołują konstruktora klasy po alokacji jak new... ale to dlatego, że w C nie ma klas)).
Awatar użytkownika
pixelenter
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 194
Rejestracja: 31 gru 2009, 15:41
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86_64

Odp: [c++] Własna dynamiczna tablica

Post autor: pixelenter »

Tak więc zrobiłem jak mówiłeś

Kod: Zaznacz cały

bool addINT(int *INT, int add, int *Objects)
{
	int *tmp;

	if( (tmp = (int*) realloc(INT, *Objects++ * sizeof(int))) == NULL )
	{
		return 0;
	}
	else
	{
		tmp[*Objects-1]=add;
		INT = tmp;
	}
	free (tmp);
	return 1;
}
Ale wywala mi coś takiego :evil:Obrazek
http://uwolnijlaptopa.pl
http://counter.li.org/cgi-bin/certificate.cgi/528644
Awatar użytkownika
dawwin
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 202
Rejestracja: 18 kwie 2009, 09:16
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [c++] Własna dynamiczna tablica

Post autor: dawwin »

Kod: Zaznacz cały

//wskażnik na wskaźnik na INT
bool addINT(int **INT, int add, int *Objects)
{
	int *tmp;
        // 'Objects' musi być preinkrementowane tzn wartość jest zwiększana przez podaniem jako argument funkcji
	if( (tmp = (int*) realloc(*INT, (++(*Objects)) * sizeof(int))) == NULL )
	{
		return false; //typ bool przyjmuje true i false (to niby odpowiedniki 1 i 0, ale bardziej eleganckie)
                // pamiętaj, że w przypadku niepowodzenia realloc() pozostawi obszar wskazywany przez *INT w stanie nienaruszonym (nie zwolni go)
	}
	else
	{
                // nawiasy dla zwiekszenia czytelności
		tmp[(*Objects)-1]=add;
                //zapisujemy pod adres wskaźnika
		*INT = tmp;
	}

        // nie zwalniamy starego obszaru - realloc zrobi to, jeśli będzie trzeba
	return true;
}
Tak ogólnie mówiąc to powinieneś to napisać w całości w C.
Niewiele się to będzie różniło od bierzącej wersji
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
pixelenter
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 194
Rejestracja: 31 gru 2009, 15:41
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86_64

Odp: [c++] Własna dynamiczna tablica

Post autor: pixelenter »

No niestety ciągle to samo co na obrazku. Może źle odwołuje się do funkcji?

Kod: Zaznacz cały

int **i;
int count=0;
addINT(i, 1, &count);
http://uwolnijlaptopa.pl
http://counter.li.org/cgi-bin/certificate.cgi/528644
Awatar użytkownika
dawwin
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 202
Rejestracja: 18 kwie 2009, 09:16
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [c++] Własna dynamiczna tablica

Post autor: dawwin »

Kod: Zaznacz cały

int *i = NULL; //wskaźnik typu int ustawiony na NULL (czyli nie wskazujący na nic)
int count=0;
addINT(&i, 1, &count); //Przekazujemy jako pierwszy argument adres do wskaźnika
Ogólnie rzeczy typu wskaźnik na wskaźnik na ... są troche zakręcone i trzeba z nimi ostrożnie
Jeśli programowałbyś tylko dla kompatybilności z c++ to polecam używać referencji zamiast wskaźników
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
pixelenter
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 194
Rejestracja: 31 gru 2009, 15:41
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86_64

Odp: [c++] Własna dynamiczna tablica

Post autor: pixelenter »

No i nareszcie działa. Dzięki wszystkim za pomoc. temat do zamknięcia
http://uwolnijlaptopa.pl
http://counter.li.org/cgi-bin/certificate.cgi/528644
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 1 gość