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

question-closed Tablica wskaźników do wskaźników, funkcja realloc

Object Storage Arubacloud
0 głosów
589 wizyt
pytanie zadane 15 lutego 2018 w C i C++ przez kaka1997 Nowicjusz (190 p.)
zamknięte 17 lutego 2018 przez kaka1997
#include <stdio.h>
#include <stdlib.h>

void addElements(int *** first) {
	int ** go = *first;
	int w; //ilosc elementow w wierszu
	scanf_s("%d", &w);
	if (**go == 0) {
		go = (int**)realloc(go, 2 * (sizeof(int*)));
		*(go + 1) = (int*)malloc((w + 1) * sizeof(int));
		*(*go + 1) = w;
		int value;
		int i;		
		for (i = 1; i < w + 1; i++) {
			scanf_s("%d", &value);
			*((*go + 1) + i) = value;
		}
		
		**go = 1;
	}
	else {
		(**go)++;
		int line = **go;
		go = (int**)realloc(go,  (line +1)* (sizeof(int*)));    //TUTAJ SIE WYWALA
	}
}

int main() {
	int ** first = (int**)malloc(sizeof(int*));
	*first = (int*)malloc(sizeof(int));
	**first = 0; // tutaj trzymam ilosc wierszy tablicy
	while (1) {
			addElements(&first);
	}
	return 0;
}

Program ma za zadanie manipulować dwuwymiarową strukturą liczb całkowitych, konkretnie dodać na początek struktury wiersz o dodanej liczbie elementów i ich wartościach. Program nie jest jeszcze dokończony. Jeśli chodzi o dodanie pierwszego wiersza działa dobrze, ale przy próbie dodania kolejnego wyskakuje błąd:  " program.exe has triggered a breakpoint " I strzałka wskazuje na funkcje realloc (tam gdzie widnieje komentarz "tutaj wywala" ). 

Dlaczego to nie działa? 

komentarz zamknięcia: W odpowiedz oznaczonej jako najlepsza jest pełne rozwiązanie problemu

3 odpowiedzi

+2 głosów
odpowiedź 15 lutego 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)
wybrane 16 lutego 2018 przez kaka1997
 
Najlepsza
Wynik realloc przypisujesz do lokalnego wskaźnika. realloc może przenieść zaalokowaną pamięć w inny obszar, na który będzie wskazywała zmienna go, ale nie *first.
komentarz 15 lutego 2018 przez kaka1997 Nowicjusz (190 p.)
Masz rację! Tutaj był błąd, wielkie dzięki :)
komentarz 15 lutego 2018 przez kaka1997 Nowicjusz (190 p.)
#include <stdio.h>
#include <stdlib.h>

void addElements(int *** first) {
	int w; //ilosc elementow w wierszu
	scanf_s("%d", &w);
	if (***first == 0) {
		*first = (int**)realloc(*first, 2 * (sizeof(int*)));
		*(*first + 1) = (int*)malloc((w + 1) * sizeof(int));
		*(**first + 1) = w;
		int value;
		int i;
		for (i = 1; i < w + 1; i++) {
			scanf_s("%d", &value);
			*((**first + 1) + i) = value;
		}

		***first = 1;
	}
	else {
		(***first)++;
		int line = ***first;
		*first = (int**)realloc(*first, (line + 1)* (sizeof(int*)));    //TUTAJ SIE WYWALA
	}
}

int main() {
	int ** first = (int**)malloc(sizeof(int*));
	*first = (int*)malloc(sizeof(int));
	**first = 0; // tutaj trzymam ilosc wierszy tablicy
	while (1) {
		addElements(&first);
	}
	return 0;
}

Przez chwilę działało (nie mam pojęcia czemu). Ale teraz znowu to samo

1
komentarz 16 lutego 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)
*(**first + 1) = w;

Piszesz po niczyjej pamięci. **first wskazuje na tego jednego inta, którego alokowałeś w mainie. Względem niego przesuwasz się o 1 i zaczynasz tam coś zapisywać. Ten sam błąd masz później w pętli.

PS. Nie wygodniej używać notacji tablicowej, np. (*first)[1] zamiast *(*first + 1)?

komentarz 16 lutego 2018 przez kaka1997 Nowicjusz (190 p.)
edycja 16 lutego 2018 przez kaka1997

Zauważ, że przekazuje argument do funkcji poprzez wskaźnik (int *** first). Dlatego wyrażenie

*(**first + 1) = w;

wskazuje na jedno inta. O wiele wygodniej używać notacji tablicowej ale jest to zadanie na studia i w poleceniu jest zakaz używania tej notacji.

EDIT: Chociaż być może masz rację, już sprawdzam

EDIT2: Tak, znowu miałeś racje, teraz program działa jak powinien. Wielkie dzięki za pomoc

0 głosów
odpowiedź 15 lutego 2018 przez Patrycjerz Mędrzec (192,320 p.)
Jeśli korzystasz z jakiegoś IDE, to zapewne kliknąłeś gdzieś przez przypadek i stworzyłeś tzw. breakpoint, czyli punkt zatrzymania kodu, często potrzebny przy debugowaniu. Znajdź ten punkt (jakaś czerwona kropka w edytorze) i go usuń.
komentarz 15 lutego 2018 przez kaka1997 Nowicjusz (190 p.)
Niestety nie o to chodzi. Nie mam utworzonych żadnych punktów breakpoint.Problem jest z tą funkcją, wydaje mi się, że źle jej używam ale nie wiem o co dokładnie chodzi. Od kilku godzin próbuję znaleźć odpowiedź ale nie mogę
komentarz 15 lutego 2018 przez Patrycjerz Mędrzec (192,320 p.)

No pewnie źle używasz. Tak w ogóle twój kod bardzo ciężko się czyta. Znalazłem jedynie to na ten moment:

sizeof(*(go+1))

Co niby wg ciebie ma to zwrócić? Przecież wtedy otrzymasz rozmiar wskaźnika, czyli te cztery lub osiem bajtów, po co tutaj cokolwiek dodawać?

komentarz 15 lutego 2018 przez kaka1997 Nowicjusz (190 p.)
Źle przepisałem kod, już poprawiony.
0 głosów
odpowiedź 15 lutego 2018 przez kaka1997 Nowicjusz (190 p.)

Zmieniłem kod zgodnie z zaleceniami:

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

void addElements(int *** first) {
	int w; //ilosc elementow w wierszu
	scanf_s("%d", &w);
	if (***first == 0) {
		*first = (int**)realloc(*first, 2 * (sizeof(int*)));
		*(*first + 1) = (int*)malloc((w + 1) * sizeof(int));
		*(**first + 1) = w;
		int value;
		int i;
		for (i = 1; i < w + 1; i++) {
			scanf_s("%d", &value);
			*((**first + 1) + i) = value;
		}

		***first = 1;
	}
	else {
		(***first)++;
		int line = ***first;
		*first = (int**)realloc(*first, (line + 1)* (sizeof(int*)));    //TUTAJ SIE WYWALA
	}
}

int main() {
	int ** first = (int**)malloc(sizeof(int*));
	*first = (int*)malloc(sizeof(int));
	**first = 0; // tutaj trzymam ilosc wierszy tablicy
	while (1) {
		addElements(&first);
	}
	return 0;
}

Niestety znowu to samo.

Ktoś może pomóc?

komentarz 15 lutego 2018 przez kaka1997 Nowicjusz (190 p.)
Problem widoczny dla przykładowego testu: 4 1 2 3 4 5

Podobne pytania

0 głosów
1 odpowiedź 143 wizyt
pytanie zadane 4 marca 2020 w C i C++ przez Programmingc100 Bywalec (2,620 p.)
–1 głos
2 odpowiedzi 1,067 wizyt
pytanie zadane 22 marca 2017 w C i C++ przez Evelek Nałogowiec (28,960 p.)
0 głosów
1 odpowiedź 544 wizyt
pytanie zadane 26 stycznia w C i C++ przez TOWaD Mądrala (5,700 p.)

92,568 zapytań

141,422 odpowiedzi

319,629 komentarzy

61,956 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!

...