¿Por qué la lista enlazada se implementa en la memoria Heap en lugar de en la memoria Stack?

Requisito previo: 

Lista vinculada Estructura de datos
Pila vs Heap Asignación de memoria

La lista enlazada es una estructura de datos lineal, en la que los elementos no se almacenan en ubicaciones de memoria contiguas. Los elementos de una lista enlazada se enlazan mediante punteros . Se implementa en la memoria del montón en lugar de la memoria de la pila . Este artículo analiza la razón detrás de esto.

Pila vs Memoria Heap

La memoria de la computadora se divide en segmentos de memoria de pila y pila. El segmento de memoria de pila es relativamente pequeño, por lo que se usa principalmente para operaciones como recursividad o declaraciones de salto de control como la declaración goto. Debido al pequeño tamaño del segmento de la pila, no se usa para niveles de recursividad profundos, ya que puede generar un error de desbordamiento de la pila.

Por otro lado, una lista enlazada tiene la gran ventaja de expandirse dinámicamente cuando sea necesario sin preocuparse por el consumo de memoria. Esta es la razón por la que se prefiere el montón para almacenar objetos de lista vinculados.

¿Por qué la lista enlazada no se almacena en la memoria de pila?

La pregunta de por qué no se puede hacer una lista enlazada con la memoria de la pila se debe a las reglas de alcance y la gestión automática de la memoria en la pila. La idea básica de una lista enlazada es enlazar Nodes en función de su dirección de memoria. Si cada Node se crea en la pila, esos Nodes se eliminarán después de que queden fuera del alcance, por lo que incluso si el usuario mantiene los punteros a su dirección de memoria, no es seguro asumir que no serán sobrescritos por otra cosa.

La lista enlazada también se puede implementar en la memoria de pila . A continuación se muestra la implementación en C++ de la creación de una lista enlazada en la memoria de pila:

C++

// C++ program to implement
// linked list in stack
#include <iostream>
using namespace std;
 
// Structure of the linked list
struct Node {
    int data;
    struct Node* next;
 
    // Constructor
    Node(int x)
    {
        data = x;
        next = NULL;
    }
}* head = NULL;
 
// Function to print the linked list
void printLinkedList(Node* head)
{
    struct Node* temp = head;
 
    // Traversing linked list
    while (temp) {
        cout << temp->data << " ";
        temp = temp->next;
    }
}
 
// Driver code
int main()
{
    // Creation of linked list in stack
    struct Node first = Node(1);
    struct Node second = Node(2);
    struct Node third = Node(3);
    struct Node fourth = Node(4);
 
    head = &first;
 
    // 1 -> 2 -> 3 -> 4
    first.next = &second;
    second.next = &third;
    third.next = &fourth;
    fourth.next = NULL;
 
    // Printing the elements of
    // a linked list
    printLinkedList(head);
 
    return 0;
}

Java

// Java program to implement
// linked list in stack
 
import java.util.*;
 
class GFG{
 
// Structure of the linked list
static class Node {
    int data;
    Node next;
 
    // Constructor
    Node(int x)
    {
        data = x;
        next = null;
    }
};
static Node head = null;
 
// Function to print the linked list
static void printLinkedList(Node head)
{
    Node temp = head;
 
    // Traversing linked list
    while (temp!=null) {
        System.out.print(temp.data+ " ");
        temp = temp.next;
    }
}
 
// Driver code
public static void main(String[] args)
{
    // Creation of linked list in stack
    Node first = new Node(1);
    Node second = new  Node(2);
    Node third = new Node(3);
    Node fourth = new Node(4);
 
    head = first;
 
    // 1.2.3.4
    first.next = second;
    second.next = third;
    third.next = fourth;
    fourth.next = null;
 
    // Printing the elements of
    // a linked list
    printLinkedList(head);
 
}
}
 
// This code contributed by shikhasingrajput

C#

// C# program to implement
// linked list in stack
using System;
using System.Collections.Generic;
 
public class GFG{
 
  // Structure of the linked list
  class Node {
    public int data;
    public Node next;
 
    // Constructor
    public Node(int x)
    {
      data = x;
      next = null;
    }
  };
  static Node head = null;
 
  // Function to print the linked list
  static void printList(Node head)
  {
    Node temp = head;
 
    // Traversing linked list
    while (temp!=null) {
      Console.Write(temp.data+ " ");
      temp = temp.next;
    }
  }
 
  // Driver code
  public static void Main(String[] args)
  {
 
    // Creation of linked list in stack
    Node first = new Node(1);
    Node second = new  Node(2);
    Node third = new Node(3);
    Node fourth = new Node(4);
 
    head = first;
 
    // 1.2.3.4
    first.next = second;
    second.next = third;
    third.next = fourth;
    fourth.next = null;
 
    // Printing the elements of
    // a linked list
    printList(head);
 
  }
}
 
// This code is contributed by shikhasingrajput

Javascript

<script>
// Javascript program to implement
// linked list in stack
 
// Structure of the linked list
class Node {
 
    // Constructor
    constructor(x) {
        this.data = x;
        this.next = null;
    }
}
 
// Function to print the linked list
function printLinkedList(head) {
    let temp = head;
 
    // Traversing linked list
    while (temp) {
        document.write(temp.data + " ");
        temp = temp.next;
    }
}
 
// Driver code
 
// Creation of linked list in stack
let first = new Node(1);
let second = new Node(2);
let third = new Node(3);
let fourth = new Node(4);
 
head = first;
 
// 1 -> 2 -> 3 -> 4
first.next = second;
second.next = third;
third.next = fourth;
fourth.next = null;
 
// Printing the elements of
// a linked list
printLinkedList(head);
 
// This code is contributed by gfgking.
</script>

Producción:

1 2 3 4 

Condición cuando la implementación de la lista vinculada en la pila no funcionará:

El código anterior no funcionará si escribimos la lógica de la creación de una lista enlazada en una función separada y la lógica de imprimir los elementos de la lista enlazada en una función separada. A continuación se muestra su implementación en C++ del concepto anterior:

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Structure of the linked list
struct Node {
    int data;
    struct Node* next;
 
    Node(int x)
    {
        data = x;
        next = NULL;
    }
}* head = NULL;
 
// Function to return the head pointer
// of the created linked list
Node* CreateLinkedList()
{
    struct Node first = Node(1);
    struct Node second = Node(2);
    struct Node third = Node(3);
    struct Node fourth = Node(4);
 
    head = &first;
 
    // 1->2->3->4
    first.next = &second;
    second.next = &third;
    third.next = &fourth;
    fourth.next = NULL;
 
    return head;
}
 
// Function to print the linked list
void printLinkedList(Node* head)
{
    struct Node* temp = head;
 
    // Traversing linked list
    while (temp) {
        cout << temp->data << " ";
        temp = temp->next;
    }
}
 
// Driver Code
int main()
{
    struct Node* head = CreateLinkedList();
    printLinkedList(head);
    return 0;
}

Java

// Java program to implement
// the above approach
 
import java.util.*;
 
class GFG{
 
// Structure of the linked list
static class Node {
    int data;
    Node next;
 
    Node(int x)
    {
        data = x;
        next = null;
    }
}
static Node head = null;
 
// Function to return the head pointer
// of the created linked list
static Node CreateLinkedList()
{
    Node first = new Node(1);
    Node second = new Node(2);
    Node third = new Node(3);
    Node fourth = new Node(4);
 
    head = first;
 
    // 1.2.3.4
    first.next = second;
    second.next = third;
    third.next = fourth;
    fourth.next = null;
 
    return head;
}
 
// Function to print the linked list
static void printLinkedList(Node head)
{
    Node temp = head;
 
    // Traversing linked list
    while (temp!=null) {
        System.out.print(temp.data+ " ");
        temp = temp.next;
    }
}
 
// Driver Code
public static void main(String[] args)
{
    Node head = CreateLinkedList();
    printLinkedList(head);
}
}
 
// This code is contributed by 29AjayKumar

C#

// C# program to implement
// the above approach
 
using System;
 
public class GFG{
 
  // Structure of the linked list
  class Node {
    public int data;
    public Node next;
 
    public Node(int x)
    {
      data = x;
      next = null;
    }
  }
  static Node head = null;
 
  // Function to return the head pointer
  // of the created linked list
  static Node CreateList()
  {
    Node first = new Node(1);
    Node second = new Node(2);
    Node third = new Node(3);
    Node fourth = new Node(4);
 
    head = first;
 
    // 1.2.3.4
    first.next = second;
    second.next = third;
    third.next = fourth;
    fourth.next = null;
 
    return head;
  }
 
  // Function to print the linked list
  static void printList(Node head)
  {
    Node temp = head;
 
    // Traversing linked list
    while (temp != null) {
      Console.Write(temp.data + " ");
      temp = temp.next;
    }
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    Node head = CreateList();
    printList(head);
  }
}
 
// This code is contributed by shikhasingrajput

Javascript

<script>
 
// javascript program to implement
// the above approach    // Structure of the linked list
     class Node
     {
        constructor( x) {
            this.data = x;
            this.next = null;
        }
    }
 
    var head = null;
 
    // Function to return the head pointer
    // of the created linked list
    function CreateLinkedList() {
        var first = new Node(1);
        var second = new Node(2);
        var third = new Node(3);
        var fourth = new Node(4);
 
        head = first;
 
        // 1.2.3.4
        first.next = second;
        second.next = third;
        third.next = fourth;
        fourth.next = null;
 
        return head;
    }
 
    // Function to print the linked list
    function printLinkedList( head) {
        var temp = head;
 
        // Traversing linked list
        while (temp != null) {
            document.write(temp.data + " ");
            temp = temp.next;
        }
    }
 
    // Driver Code
        var head = CreateLinkedList();
        printLinkedList(head);
         
// This code contributed by shikhasingrajput
</script>

Explicación:

El código anterior da el veredicto como FALLA DE SEGMENTACIÓN . La razón detrás de esto es que durante la creación de la lista enlazada en la memoria de la pila, todos los objetos creados por una función desaparecerán a medida que se abre el marco de la pila cada vez que la función finaliza o regresa. Consulte este artículo para conocer la razón detrás de la aparición del marco de pila cada vez que finaliza la función.

¿Por qué la lista vinculada se almacena en la memoria del montón?

En una lista enlazada, cuando es necesario almacenar más datos, podemos asignar la memoria en tiempo de ejecución usando malloc o una nueva función en C/C++. Por lo tanto, la asignación de memoria dinámica reserva el tamaño del área del montón, por lo tanto, una lista vinculada se almacena en la memoria del montón.
Si es necesario almacenar listas vinculadas en el área de la pila, implemente listas vinculadas sin usar malloc o una nueva función.

A continuación se muestra el programa C++ para mostrar cómo implementar una lista vinculada en la memoria del montón sin generar un error de falla de segmentación:

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Structure of the linked list
struct Node {
    int data;
    struct Node* next;
};
struct Node* head = NULL;
 
// Function to create nodes of
// the linked list
void CreateLinkedList(int new_data)
{
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = head;
    head = new_node;
}
 
// Function to print the linked list
void printLinkedList()
{
    struct Node* temp;
    temp = head;
 
    // Traversing linked list
    while (temp != NULL) {
        cout << temp->data << " ";
        temp = temp->next;
    }
}
 
// Driver Code
int main()
{
    CreateLinkedList(1);
    CreateLinkedList(2);
    CreateLinkedList(3);
    CreateLinkedList(4);
    printLinkedList();
    return 0;
}

Java

// Java program to implement
// the above approach
import java.util.*;
public class GFG{
 
// Structure of the linked list
static class Node {
    int data;
    Node next;
};
static Node head = null;
 
// Function to create nodes of
// the linked list
static void CreateLinkedList(int new_data)
{
    Node new_node = new Node();
    new_node.data = new_data;
    new_node.next = head;
    head = new_node;
}
 
// Function to print the linked list
static void printLinkedList()
{
    Node temp;
    temp = head;
 
    // Traversing linked list
    while (temp != null) {
        System.out.print(temp.data+ " ");
        temp = temp.next;
    }
}
 
// Driver Code
public static void main(String[] args)
{
    CreateLinkedList(1);
    CreateLinkedList(2);
    CreateLinkedList(3);
    CreateLinkedList(4);
    printLinkedList();
}
}
 
// This code is contributed by 29AjayKumar

C#

// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Structure of the linked list
  public class Node {
    public int data;
    public Node next;
  };
 
  static Node head = null;
 
  // Function to create nodes of
  // the linked list
  static void CreateList(int new_data) {
    Node new_node = new Node();
    new_node.data = new_data;
    new_node.next = head;
    head = new_node;
  }
 
  // Function to print the linked list
  static void printList() {
    Node temp;
    temp = head;
 
    // Traversing linked list
    while (temp != null) {
      Console.Write(temp.data + " ");
      temp = temp.next;
    }
  }
 
  // Driver Code
  public static void Main(String[] args) {
    CreateList(1);
    CreateList(2);
    CreateList(3);
    CreateList(4);
    printList();
  }
}
 
// This code is contributed by umadevi9616

Javascript

<script>
// javascript program to implement
// the above approach
 
    // Structure of the linked list
     class Node {
         constructor(){
        this.data = 0;
        this.next = null;
    }
    }
    var head = null;
 
    // Function to create nodes of
    // the linked list
    function CreateLinkedList(new_data)
    {
        var new_node = new Node();
        new_node.data = new_data;
        new_node.next = head;
        head = new_node;
    }
 
    // Function to print the linked list
    function printLinkedList()
    {
        var temp;
        temp = head;
 
        // Traversing linked list
        while (temp != null) {
            document.write(temp.data + " ");
            temp = temp.next;
        }
    }
 
    // Driver Code
        CreateLinkedList(1);
        CreateLinkedList(2);
        CreateLinkedList(3);
        CreateLinkedList(4);
        printLinkedList();
 
// This code is contributed by umadevi9616
</script>

Producción:

4 3 2 1

Lista vinculada en Stack vs Heap Memory

No. S. Lista vinculada en la memoria de pila Lista vinculada en la memoria del montón
1 La lista vinculada en la pila obtendrá acceso a una memoria relativamente pequeña que no se puede expandir dinámicamente. La lista vinculada en el montón obtendrá acceso a la memoria dinámicamente expandible.
2 Cada Node creado en la lista vinculada y almacenado en la pila se vinculará y eliminará después de que quede fuera del alcance. Es necesario liberar la memoria para que se elimine el Node.
3 Si es necesario almacenar una lista vinculada en el área de la pila, implemente una lista vinculada sin usar malloc o una nueva función. Si es necesario almacenar la lista vinculada en el montón, implemente la lista vinculada utilizando malloc o la nueva función.
4 No se puede acceder a los Nodes de la lista vinculada creados en la pila una vez que finaliza el alcance de la función. Se puede acceder a los Nodes de la lista vinculada creados y almacenados en la memoria del montón una vez que finaliza el alcance de la función.

Publicación traducida automáticamente

Artículo escrito por dnpuneeth y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *