legat lista liniară Izolat

Te rog să mă ierți pentru arogantă meu generos, dar aș dori să identifice o altă sursă de probleme potențiale. Dacă luăm în considerare performanța de mediu multi-threaded, toate aceste funcții nu au capacitatea de a re-intrat, și anume nu fir în condiții de siguranță. În sensul că procedura de legare sau șterge lista nodurilor pentru a fi o operație atomică, adică cod în porțiunea în care manipulările efectuate pe indicii și câmpurile de date trebuie să fie situate într-o secțiune critică, ceva de genul

p = lst-> ptr; // Salvați pointerul la nodul următor
lst-> = temp ptr; // nod creat anterior indică
temp-> câmp = număr; // câmp salva date adăugat nod
temp-> = p ptr; // Crearea unei puncte de nod la elementul următor

Luați în considerare acest exemplu. Să lista noastră este formată din 3 elemente:

root => elem1 => elem2 => elem3 => NULL

Să presupunem că există două fluxuri paralele (sarcini, fire, etc., pe platforme diferite, este numit în diferite moduri, dar esența nu se schimbă), în care dorim să adăugați un element la sfârșitul listei (pseudo-cod în ordinea performanței sale în timp)

// Stream 1
// aici un cod
last_element = find_last_elem (rădăcină); // Ia un pointer la ultimul element
addelem (last_elem, număr); // adauga un nou element la sfârșitul listei
// aici un cod

// Stream 2
// aici un cod
last_element = find_last_elem (rădăcină); // Ia un pointer la ultimul element
addelem (last_elem, număr); // adauga un nou element la sfârșitul listei
// aici, ce cod care

deși în momentul în care fluxul este executat și 1 avem un pointer la ultimul element, în acest caz, elementul 3, și funcția apoi a provocat addelem (), care începe să fie îndeplinite:

temp = (lista struct *) malloc (sizeof (lista));
p = lst-> ptr; // Salvați indicatorul la nodul următor, în acest caz, este ultima p = NULL

// Uups! Executie mutat la firul 2 nu există nici o garanție că acest lucru nu se poate întâmpla în acest loc

// flux 2 - acum suntem în fluxul 2

// găsi ultimul element al listei - aceasta (ce surpriză.) Punctul 3, după cum noi pur și simplu nu au timp pentru a remap indicii //
// acum am intrat din nou funcția addelem ()

temp = (lista struct *) malloc (sizeof (lista));
p = lst-> ptr; // Salvați pointerul la nodul următor este NULL
lst-> = temp ptr; // indica faptul creat nodul precedent, este acum elementul 4
temp-> câmp = număr; // câmp salva date adăugat nod
temp-> = p ptr; // Crearea unei puncte de nod la elementul următor, în acest caz, NULL
întoarce (temp);

// returneaza flux în funcție 2
// trebuie să avem următoarea listă de root => elem1 => elem2 => elem3 => elem4 => NULL
// face unele flux de cod 2
// oops. din nou, de comutare pe flux 1.

// Stream 1
// continua de la punctul la care a întrerupt

// LST încă indică elementul 3, cu toate că acest lucru nu este ultimul element din listă.
lst-> = temp ptr; // indica este creat nodul anterior, dar nu este un element adăugat 4 în fluxul 2
// pointer la astfel, elementul 4 creat flux suprascrisă 2
temp-> câmp = număr; // câmp salva date adăugat nod
temp-> = p ptr; // Crearea unei puncte de nod la elementul următor
întoarce (temp);

// a reveni la funcția flux 1, sa execute un anumit flux de cod 1

Deci, pentru a rezuma, ceea ce vedem. Vedem că membru caseta 3 PTR pointer la elementul 4 se adaugă la sfârșitul listei în fluxul 2, valoarea veche este suprascris în potoke1, și el este pierdut. În plus față de pierderea elementului în sine, se creează o situație periculoasă o scurgere de memorie, deoarece un pointer la un element 4 creat în fluxul de 2 pierdute în mod iremediabil, și nu putem avea în nici un mod de a elibera memoria alocată pentru ea.

Alo Multumesc pentru articol bun. Se aplică metoda de transpunere a două link-uri pentru a modifica valorile minime și maxime în listă. Pentru a găsi link-uri folosind alte funcții. În momentul de față, funcționează, dar numai în cazul în care link-urile din mijloc, și anume, nu primul și nici ultimul. Nu contează, un număr de elemente sau nu. Sfătui cum să scrie condiția pentru ambele opțiuni pentru a face totul să funcționeze. Multumesc anticipat.

anula switchMinMax (Node * cap) Nod * prevMax, * prevMin, * postMax, * postMin, * tmp;
Nod * Max, * min;
Max = getMax (cap);
Min = getMin (cap);

prevMax = cap;
prevMin = cap;
if (prevMax == Max)
prevMax = NULL;
altfel
în timp ce (prevMax-> următor! = max)
prevMax = prevMax-> următor;
if (prevMin == Min)
prevMin = NULL;
altfel
în timp ce (prevMin-> următor! = min)
prevMin = prevMin-> următor;
postMax = Max> următor;
postMin = Min-> următor;
if (min == postMax)
Min-> următor = Max;
Max> next = postMin;
dacă (Max! = cap)
prevMax-> următor = Min;
if (Max == cap)
prevMin = NULL;
>
else if (Max == postMin)
Max> next = Min;
Min-> next = postMax;
dacă (Min! = cap)
prevMin-> următor = Min;
if (min == cap)
prevMax == NULL;
>
altfel
dacă (Max! = cap)
prevMax-> următor = Min;
Min-> next = postMax;
dacă (Min! = cap)
prevMin-> următor = Max;
Max> next = postMin;
>
>

Buna ziua! Poate cineva ajuta, nu primesc nici o rezolva problema de acest tip, este necesar să se formeze o stivă de numere și să aducă într-o nouă listă la maximum a primei stivă - listă. Decizia mea, totul funcționează cu excepția copiei într-o nouă listă. aici ea funcție de înregistrare (stiva este deja plin)

Este necesar în ciclul pentru a determina elementul maxim și amintiți-vă indicatorul său.

struct stivă * maxelem = începe;
int max = maxelem-> număr;
în timp ce (temp = NULL!) if ((temp-> număr)> max) maxelem = temp;
max = (temp-> număr);
>
temp = temp-> următor;
>

Numai atunci, când știm elementul maxim și un pointer la acesta, puteți genera o nouă listă.

Multe mulțumiri pentru răspuns rapid. Cred că nu înțeleg ceva, indicatorul definit la elementul maxim, a adus o nouă listă de valori, dar consola nu afișează. Ați putea vedea, vă mulțumesc foarte mult pentru ajutor.

Eroare în linia selectată. Ai închis indicatorul la elementul în sine. Câmp pointer la elementul următor trebuie să fie inițializat în momentul creării acestui element „următor“.

struct Stiva * new_list = (struct stivă *) malloc (sizeof (struct stiva));
new_list-> număr = begin-> număr; // aceasta este rădăcina noii liste
new_list-> următor = NULL;
în timp ce (Temp2 = maxelem!) struct stivă * temp3 = new_list;
new_list = (stiva struct *) malloc (sizeof (struct stiva));
new_list-> număr = temp2-> număr;
temp3-> next = new_list;
new_list-> următor = NULL;
Temp2 = temp2-> următor;
>

În funcție de addelem (), va trece un pointer la elementul, după care este necesar pentru efectuarea adăugării. Lista indicatorul rădăcină, astfel, ar trebui să fie stocate într-o altă variabilă, iar lista de ieșire trebuie să fie realizată cu rădăcină.

În acest caz, avem nevoie de o funcție care va adăuga un element la partea de sus a listei, ca aceasta

Lista struct * addroot (lista * rădăcină, numărul int) Lista struct temp *;
temp = (lista struct *) malloc (sizeof (lista));
temp-> = root ptr; // generat de nodul rădăcină anterioară
temp-> câmp = număr; // câmp salva date adăugat nod
întoarce (temp); // returneaza noua rădăcină a listei
>

articole similare