Zapobiegnięciu utworzenia śmieci w C

Zapobiegnięciu utworzenia śmieci w C
BR
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:11
0

Witam,
przeglądam pewne arkusze egzaminacyjne. Natrafiłem na takie zadanie:

Kopiuj
 
#include<stdlib.h> //1
int *bb, aa[2][3], cc, dd, ee; //2
main(){ //3
long int aa, *hh[2],*cc; //4
for(aa=1;aa<=4;aa++){ //5 M0
long int *dd=&aa; //6
hh[aa%2]=(int*)malloc(3*sizeof(int)); //7 M1
switch(*dd){ //8
case 1: bb=hh[1]; //9 M2
case 2: cc=hh[0]; //10
} //11
} //12
if(1){ //13
char bb=’a’, cc[2]={bb++}; //14
dd=(bb+cc[1])/(*cc); //15 M3
while(0){ //16
static int bb=1, cc, dd; //17
double ff=aa; //18
cc=(int)ff; //19 M4
} //20
} //21
//22 M5
} //23

Napisz fragment kodu, który umieszczony w linii 22
zapobiegnie utworzeniu śmieci.
Czy wystarczy użyć funkcji free?

grzesiek51114
grzesiek51114
To co trzeba byłoby zrobić to iść do autora tego zadania i powiedzieć: "Stary! Puknij Ty się w łeb." Generalnie chodzi tutaj o free ale całość to tak jak @kq napisał. Współczuję jeżeli cała reszta też tak wygląda.
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Szczecin
5

Szczerze mówiąc, najbardziej mi pasuje

Kopiuj
system("rm -rf " __FILE__);

A tak bardziej serio:

Kopiuj
#include <stdlib.h> //1
int *bb, aa[2][3], cc, dd, ee; // 2
int main()
{ // 3
    long int aa, *hh[2], *cc; // 4
    for (aa = 1; aa <= 4; aa++)
    { // 5 M0
        long int* dd = &aa; // 6
        hh[aa % 2] = (int*)malloc(3 * sizeof(int)); // 7 M1
        switch (*dd)
        { // 8
            case 1:
                bb = hh[1]; // 9 M2
            case 2:
                cc = hh[0]; // 10
        } // 11
    } // 12
    if (1)
    { // 13
        char bb ='a', cc[2] = { bb++ }; // 14
        dd = (bb + cc[1]) / (*cc); // 15 M3
        while (0)
        { // 16
            static int bb = 1, cc, dd; // 17
            double ff = aa; // 18
            cc = (int)ff; // 19 M4
        } // 20
    } // 21
    // 22 M5
} // 23

malloc wywołany jest 4 razy, więc musisz dodać tyle samo odpowiadających wywołań free. W tym przypadku wygląda na to, że powinieneś dopisać (jeszcze sprawdzę, ale wydaje mi się, że jest ok sprawdziłem, valgrind potwierdza):

Kopiuj
free(hh[0]);
free(hh[1]);
free(cc);
free(bb);

Tak czy inaczej zadanie fatalne. Beznadziejne formatowanie, same złe praktyki, niekompilujący się kod i UB. Nic tylko pogratulować.


edytowany 3x, ostatnio: kq
grzesiek51114
grzesiek51114
Od samego patrzenia w ten kod, sformatowany czy nie, dostaję oczopląsu. Jeżeli egzaminatorzy chcą zrazić uczniów do programowania to uda im się to.
kq
Tak, to jest istna tragedia...
grzesiek51114
grzesiek51114
@kq jakby miało się w taki sposób pisać programy to już naprawdę wolałbym zostać spawaczem. :)
kq
No cóż, zakładając, że to uczelnia, to idealnie wpasowuje się w moją tezę (znaczna większość pracowników uczelni należy do jednej z 2 grup: 1) ludzie odrzuceni przez rynek pracy 2) pasjonaci)
4

Zapobiegnięciu utworzenia śmieci w C

Za późno.

wujnia
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:161
4

Nie za bardzo wiem czego to zadanie ma nauczyć. Utworzenie jakich śmieci. Całe zadanie to śmieć.

Chvba chodzi o uwolnienie pamięci. Co wcale nie jest jakoś super ważne w momencie zakończenia działania programu imho.

free( bb );
free( cc );
free( hh[0] );
free( hh[1] );

a już ktoś rozwiązał..

edytowany 1x, ostatnio: wujnia
BR
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:11
0

To tylko jeden z podpunktów. Niestety większość zadań z tego przedmiotu to zadania "pułapki", które na 1, a nawet 2 rzut oka przyprawiają mnie o ból głowy. Dziękuję Wam za pomoc, leczy za godzinkę jadę na egzamin i mam nadzieję, że nikt się nie obrazi jak tutaj wkleję 2 krótkie pytania.
Jakie są aliasy w tym kodzie?
I z kolejne zadania co oznacza ta linijka:
((&ee[1])-1)[1]=16;
ee jest tablicą [2];
Rozumiem, że bierzemy adres pamięci z... no właśnie.

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Szczecin
3

mam nadzieję, że nikt się nie obrazi jak tutaj wkleję 2 krótkie pytania.

Jak nie będzie to podczas egzaminu to nie :​)

((&ee[1])-1)[1]=16;:

  • ee[1] to drugi element tablicy ee
  • &ee[1] to adres drugiego elementu tablicy ee
  • (&ee[1])-1 to adres drugiego-1 elementu tablicy ee (czyli pierwszego). Od teraz (&ee[1])-1 to tmp
  • (tmp)[1] to to samo co tmp[1]
  • Dla wskaźników a[b] jest równoznaczne z b[a] oraz *(a+b) (gdzie a i b to wartość liczbowa i wskaźnik, obojętnie które jest które). Nie wiem który z tych zapisów jest dla Ciebie najprzystępniejszy. W każdym razie: w C i C++ tablica i wskaźnik na jej pierwszy element to prawie to samo. Tak więc tmp[1] to drugi element "tablicy" tmp (w każdym razie, następny za tym na który tmp wskazuje).
  • inaczej mówiąc, jeśli tmp wskazuje na pierwszy element tablicy ee to tmp[1] to drugi element tablicy ee
  • tmp[1] = 16 - przypisujesz 16 do drugiego elementu tablicy ee.

To jest bzdura a nie egzamin.


BR
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:11
0

Teraz dopiero widzę, jaki ten kod jest nielogiczny. Dzięki, mógłbyś mi jeszcze podpowiedzieć odnośnie tych aliasów (tak, mamy zadania by je wskazać).

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Szczecin
1

Chodzi o wskaźniki wskazujące na te same dane? Przyznam, że nie chce mi się już takich głupot analizować.


BR
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:11
0

Właśnie nie mam zielonego pojęcia. Szukałem definicji aliasów w programowaniu, ale bez większych rezultatów.

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Szczecin
2

No dobra, to nie wiem. Może prowadzący ma skrypt, który wymaga abyście kupili do zaliczenia zajęć...

Jeśli chodzi o przesłanianie nazw zmiennych, to wszystkie redefinicje aa, bb, cc, dd

Jeśli chodzi o strict aliasing to tam gdzie przypisujesz int* do long int*.

Może ktoś ma jakieś inne pomysły?


BR
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:11
0

Dziękuję ponownie za pomoc :)

MO
To jeszcze zdradź w jakim mieście jest taka "łuczelnia" która tak "łuczy" :-/
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

@breedovsky: Napisz chociaż później ja poszło :D

vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
4

Ten kod podchodzi pod sąd polowy i nie ma nic wspólnego ze zdobywaniem wiedzy.
Autor tego kodu chyba nigdy nie pracował z prawdziwym kodem, bo normalny programista miałby wstręt przed napisaniem czegoś takiego.
Może nikt go nie chciał przyjąć do normalnej roboty.

Dodatkowo ktoś chyba chce Wam obrzydzić jakże piękny i prosty język C.
W zasadzie to można by ten egzamin zaskarżyć do dziekana.

Oczywiście da się to rozwiązać po refaktoringu, ale autor chyba nie wie co to jest.

0

Pierwsze co mi przyszło do głowy z tym aliasing to typedef ??? Ale wygląda, że chodzi o sytuacje gdy dwa pointery wskazują tą samą pamięć.

several
  • Rejestracja:ponad 15 lat
  • Ostatnio:minuta
0

Skoro to z arkuszu egzaminacyjnego, to może specjalnie jest tak napisany, żeby było trudniej namierzyć jakie free dodać. Kaszanka straszna.


vpiotr
Ciekaw jestem ile procent ludzi którzy mogliby zostać programistami faktycznie by nimi zostało gdyby dostawali w szkole zadania z analizy kodu z IOCCC.
BR
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:11
0

Egzamin w podobnym stylu, rozbudowany kod na kartce, przepisze go z kartki, jak nie zadziała minus ileś tam procent. Sprawdzanie stanów pamięci na jeszcze gorszym kodzie niż w przykładzie i pytania o zasiegi zmiennych itp. Uczelnia w Warszawie, często kpiaco nazywana ukswordem :)
Dziękuję za pomoc i odswiezam usos :P
PS. Czas zmienić uczelnia :)

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)