Zapobiegnięciu utworzenia śmieci w C

0

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

 
#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?

5

Szczerze mówiąc, najbardziej mi pasuje

system("rm -rf " __FILE__);

A tak bardziej serio:

#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):

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ć.

4

Zapobiegnięciu utworzenia śmieci w C

Za późno.

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ł..

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.

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.

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ć).

1

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

0

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

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?

0

Dziękuję ponownie za pomoc :)

0

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

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ęć.

0

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

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 :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1