Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Język C - [c][wskaźniki] Błąd przy uwalnianiu pamięci (usuwaniu wskaźników)

Kryspin92 27 Gru 2012 15:44 1788 20
  • #1 27 Gru 2012 15:44
    Kryspin92
    Poziom 10  

    Mój program służy do tworzenia macierzy i następnie robieniu na nich różnych operacji matematycznych. Na razie tylko dodaje do siebie macierze. W końcu przypomniałem sobie że muszę uwolnić pamięć na końcu programu... Lecz tu nie mam wskaźnika tylko pierw mam tablice wskaźników... więc usuwam wszystko wg schematu:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Wszystko działa do momentu kiedy nie wypełnię tablicy dynamicznej danymi
    gdy to zrobię wyskakuję błąd (obrazek)
    cały projekt z MS Visual C++ 2010 dodaje w załączniku
    Język C - [c][wskaźniki] Błąd przy uwalnianiu pamięci (usuwaniu wskaźników)

    Tak już uprzedzam niemiłe komentarze... jest to zadanie na studia ale nie mam pojęcia o co chodzi z tym błędem...

    0 20
    Załączniki:
  • #2 27 Gru 2012 15:48
    stanleysts
    Poziom 27  

    Za dużo miejsca chcesz zaalokować, musisz prawdopodobnie zwiększyć pojemność sterty.

    0
  • #3 27 Gru 2012 15:52
    Kryspin92
    Poziom 10  

    Błąd pokazuje się dopiero w momencie wykonywania funkcji free()
    cała reszta śmiga równo i poprawnie

    0
  • #4 27 Gru 2012 16:15
    stanleysts
    Poziom 27  

    Wogóle to powinieneś chyba zrobić tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 27 Gru 2012 16:39
    Kryspin92
    Poziom 10  

    Nie wiem, nie ma to większego znaczenia mi się wydaję, bo i typ liczb całkowitych i typ adresowy ma po 4 bajty... przynajmniej tak pokazuje mi mój kompilator.
    sizeof (**pmacierz)
    sizeof (*pmacierz)
    sizeof (int)
    Wszystkie te funkcje zwracają wartość 4, więc przy obliczeniach nie sprawia to większego problemu, bo funkcja malloc() chce tylko konkretną liczbę bajtów.

    0
  • #6 27 Gru 2012 17:16
    Krzysztof Gustaw
    Poziom 23  

    Witam!
    Skoro, jak piszesz na początku, Twój program nie wyrzuca błędu dopóki nie wypełnisz danymi przydzielonych tablic, to błędu musisz szukać w kodzie który zapisuje dane. A tak w ogóle sądzę, że w tym przypadku konieczne jest użycie wskaźników do n-elementowych tablic typu int, a nie wskaźników do elementów typu int, skoro działasz na macierzach a nie na wektorach.

    0
  • #7 27 Gru 2012 19:05
    stanleysts
    Poziom 27  

    Może i zwraca po 4 ale jak sie pisze to tak, żeby było czytelnie i sensownie a nie żeby działało, skąd mam wiedzieć że u ciebie int to 4B a nie np 2...

    0
  • #8 27 Gru 2012 20:15
    Kryspin92
    Poziom 10  

    Mówię przecież że błąd jest dopiero gdy chcę usunąć wskaźniki. Tak to wskaźniki działają bezbłędnie.

    0
  • #9 28 Gru 2012 09:01
    krru
    Poziom 32  

    Bo gdzieś zamazujesz pamięć poza obszarami przydzielonymi - najczęściej tak się zdarza, jak występuje indeksowanie poza przydzielony rozmiar tablicy. Gdy użytkownik przydziela pamięć, pobierane jest jej trochę więcej na informacje organizacyjne (np. rozmiar przydzielonego bloku), poza tym pomiędzy przydzielonymi blokami występują bloki wolne. Podczas zwalniania procedura free czyta te informacje i sprawdza czy coś się nie popsuło. Np. może wyjść, że jeden blok zachodzi na drugi - np. gdy program zamazał informację o wielkości bloku. To jest właśnie taki błąd jak sygnalizowany w tym okienku - heap corrupted.

    0
  • #10 28 Gru 2012 09:49
    stanleysts
    Poziom 27  

    Cytat:
    Mówię przecież że błąd jest dopiero gdy chcę usunąć wskaźniki. Tak to wskaźniki działają bezbłędnie.


    No dobrze, ale to źle robiłeś i dlatego to podkreśliłem, to że działa "przypadkowo" dobrze to tylko fart.
    A jeśli nie wykonujesz żadnych operacji między przydzielaniem a zwalnianiem miejsca to się też wysypuje?

    0
  • #11 03 Sty 2013 14:07
    Kryspin92
    Poziom 10  

    Właśnie nie występuje żaden błąd i to mnie dziwi

    0
  • #12 04 Sty 2013 16:13
    stanleysts
    Poziom 27  

    No bo jest tak jak Ci kolega wyżej pisał.

    0
  • #13 04 Sty 2013 17:25
    Kryspin92
    Poziom 10  

    stanleysts napisał:
    Wogóle to powinieneś chyba zrobić tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Zrobiłem tak jak mówiłeś i teraz tworząc mniejszy program aby było mniej do analizowania wyskakuje ten sam błąd:
    main.cpp:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    wszystkie funkcje normalnie są w różnych plikach ale na forum zrobiłem to w jednym pliku...
    zawartość pliku o nazwie "jeden.mat"(w programie należy napisać nazwę bez rozszerzenia):
    Code:

    3 3
    1
    2
    3
    /kw/
    4
    3
    2
    /kw/
    1
    2
    3
    /kw/



    Czy możecie mi powiedzieć w którym miejscu źle myślę ?

    0
  • #14 04 Sty 2013 17:34
    stanleysts
    Poziom 27  

    To jest źle napewno:

    bool dodroz(char nazwa[], char roz[3])

    Jak mu podajesz tablice też jako drugi argument to ma być:
    bool dodroz(char nazwa[], char roz[])

    0
  • #15 04 Sty 2013 19:55
    Kryspin92
    Poziom 10  

    stanleysts napisał:
    To jest źle napewno:

    bool dodroz(char nazwa[], char roz[3])

    Jak mu podajesz tablice też jako drugi argument to ma być:
    bool dodroz(char nazwa[], char roz[])


    Zgadzam się ale w sumie to działało (wpisałem 3 bo chciałem ograniczyć jakoś wielkość tablicy ale to niepotrzebnie) ale nadal nie rozwiązuje to mojego problemu.
    wskaźnik **pmacierz wypełniony danymi nadal nie daje się usunąć z pamięci i jest błąd

    0
  • #16 04 Sty 2013 20:06
    beluosus
    Poziom 25  

    stanleysts napisał:
    To jest źle napewno:

    bool dodroz(char nazwa[], char roz[3])

    Jak mu podajesz tablice też jako drugi argument to ma być:
    bool dodroz(char nazwa[], char roz[])
    na pewno*

    Śmieszne rzeczy. :) Rozmiar tablicy ma znaczenie dopiero przy drugim i dalszych wymiarach (potrzebne to jest do obliczenia pozycji w pamięci).

    Co do problemu to tak pobieżnie patrząc problem leży tutaj:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Powinien być <, a nie <=, wtedy piszesz poza mat. Btw nie musisz podawać referencji, żadnej oszczędności tu nie będzie (tak czy siak przekażesz tę samą ilość bajtów przez argument), a adresu wskaźnika nie zmieniasz.

    0
  • #17 04 Sty 2013 21:04
    Kryspin92
    Poziom 10  

    beluosus napisał:

    Co do problemu to tak pobieżnie patrząc problem leży tutaj:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Powinien być <, a nie <=, wtedy piszesz poza mat. Btw nie musisz podawać referencji, żadnej oszczędności tu nie będzie (tak czy siak przekażesz tę samą ilość bajtów przez argument), a adresu wskaźnika nie zmieniasz.


    Kod: c
    Zaloguj się, aby zobaczyć kod


    ta pętla nie powoduje że mat zajmuje więcej miejsca bo j = 3 (przy s = 3) jest tylko do sprawdzenia czy aby na pewno jest to koniec wiersza... (mógłby taki błąd wystąpić przy błędnym pliku to prawda ale to nic nie zmienia)

    0
  • Pomocny post
    #18 04 Sty 2013 21:11
    beluosus
    Poziom 25  

    Ah, nie powiedziałeś co jest zawartością pliku, jak rozumiem na końcu każdego wiersza jest "/kw/". Ale błąd jest nadal, bo porównujesz adresy, a nie tekst. Spróbuj:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #19 04 Sty 2013 22:39
    Kryspin92
    Poziom 10  

    beluosus napisał:
    Ah, nie powiedziałeś co jest zawartością pliku, jak rozumiem na końcu każdego wiersza jest "/kw/". Ale błąd jest nadal, bo porównujesz adresy, a nie tekst. Spróbuj:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Pomogło nie mogę uwierzyć ha ha od 2 tygodni się zastanawiałem o co tu chodzi... a więc
    Kod: c
    Zaloguj się, aby zobaczyć kod

    zawsze zwracała fałsz ?

    0
  • Pomocny post
    #20 04 Sty 2013 22:56
    beluosus
    Poziom 25  

    Krótko mówiąc, tak. :)

    0
  • #21 04 Sty 2013 23:05
    Kryspin92
    Poziom 10  

    Dzięki ci bardzo :) ha ha moje zaliczenie jest uratowane :)

    0