Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Tablice Dynamiczne z funkcja malloc

kokodyn 01 Mar 2017 22:31 780 4
  • #1
    kokodyn
    Level 10  
    Z góry dziękuje za wszelką okazaną pomoc, czy mógłby ktoś proszę sprawdzić ten kod?
    Program ma za zadanie stworzyć tablicę wskaźników. z których każdy wskazuje na obiekt o rozmiarze dokładnie odpowiadającym, rozmiarowi przechowywanego w nich ciągu znaków. W książce jest określone że wskaźnik użyty do przechowywania wartości zwracanej z malloc() powinien być typu wskaźnik do wskaźnika do char. U mnie jest to char *pointer[words]; czy to jest poprawnie?
    Ta wersja się kompiluje i uruchamia, problem jest w nadpisywaniu się kolejnych iteracji pętli for. Program zaczyna nie poprawnie pracować dla words > 2
    Code: c
    Log in, to see the code
  • #2
    JacekCz
    Level 39  
    Jestem zdziwiony gdy mówisz, że to się kompiluje, wg mnie nie, deklaracja tablicy o nieokreślonym wymiarze, to jest nielegalne. Nawet gdyby jakimś cudem było skompilowane, sens odbiega od tego, co oczekujesz. Jakim kompilatorem to robisz?

    Code: c
    Log in, to see the code


    Tutaj alokujesz o jeden znak za mało (na kończący \0), w konsekwencji niszczysz "jakiś" kawałek pamięci.
    Code: c
    Log in, to see the code


    C/C++ pełne jest tzw Undefined Behaviour, czyli w praktyce błędów, których skutek nie musi się ujawnić szybko, albo w wyrazisty sposób. Mogą być tzw 'czary'

    EDIT: na zasadzie dobrych praktyk jak bym unikał trafiania w nazwy funkcji/typów które gdzieś w calym ekosystemie C (w tym C++) są zdefiniowane, tzn myślę o read i string.
  • #3
    kokodyn
    Level 10  
    Cześć, dziękuje bardzo za odpowiedź. Używam środowiska Geany na Ubuntu i kompilator to gcc. Czy polecałbyś jakieś inne środowiska, skoro uważasz że to nie powinno się skompilować?
    Wprowadziłem 3 poprawki i program zaczął działać poprawnie.

    -przesunąłem definicje tablicy wskaźników do miejsca gdzie words znana jest już wartość zmiennej words
    -oraz zwiększyłem rozmiar alokowanej pamięci
    -zmieniłem nazwy string na string1 i read na read1

    Code: c
    Log in, to see the code
  • Helpful post
    #4
    JacekCz
    Level 39  
    bezpośredniego skutku zwykle nie ma (sizeof(char)==1), ale zamiast

    Code: c
    Log in, to see the code


    ma być

    Code: c
    Log in, to see the code


    Pytanie o kompilator (wersję, opcje uruchomieniowe) jest o tyle ważne, że C jest 'dziwnie' zestandaryzowane, w praktyce ważniejsza jest wiedza o kompilatorze niż jakiś formalny standard.

    Przeniesienie deklaracji już jest formalnie poprawne (nie od zawsze, dla dialektów C gdzieś od 2005 roku), tym niemniej jest to tablica na stosie (typu auto), a wątek sugeruje dynamiczną (alokowaną). Na hipotetycznych architekturach z limitowanym stosem to może być problem.

    kokodyn wrote:

    -zmieniłem nazwy ... read na read1


    Ja bym zmienił na znaczącą, oddająca intencję projektową. Coś w rodzaju read_and_trim albo read_from_line czy read_one_from_line
    Nazwa która wyznacza funkcjonalność pomaga (nawet w projekcie jednoosobowym) się zdyscyplinować. A nie ukrywajmy, funkcja z kilkoma czynnościami ma duże zagrożenia na to, by jej specyfikację naciągać do bałaganu (ku własnym pomyłkom)
  • #5
    kokodyn
    Level 10  
    Ok poprawiłem wskazane fragmenty kodu.
    Code: c
    Log in, to see the code