没有malloc的C中的链接列表

let*_*tsc 17 c malloc linked-list

#include <stdio.h>

typedef struct node
{
      int i;
      struct node *next;
}node;

node getnode(int a)
{
      struct node n;
      n.i=a;
      n.next=NULL;
      return n;
}

main()
{
     int i;
     node newtemp,root,temp;

     scanf("%d",&i);
     root=getnode(i);
     temp=root;

     while(i--)
     {
         newtemp=getnode(i);

         temp.next=&newtemp;
         if(root.next==NULL)
         {
            root=temp;
         }
        temp=*(temp.next);
     }


     temp=root;

     while( temp.next != NULL )
     {
         printf(" %d ",temp.i);
         temp=*(temp.next);
     }
}
Run Code Online (Sandbox Code Playgroud)

我试图在不使用malloc的情况下创建链表.编程只打印根,后面没有节点.我找不到这个bug.如果有任何内存问题,gcc编译器会抛出一个分段错误.(?)请忽略糟糕的编程风格..

Joh*_*all 17

初始化时temp.next,指定给它的指针的值是多少?

temp.next=&newtemp;
Run Code Online (Sandbox Code Playgroud)

为什么,每次都是一样的!(如果你不相信,请画一幅画.)

放弃.如果您需要不确定数量的内存(使用不确定数量的节点),则需要分配内存.


Pet*_* G. 11

你可以避免malloc但不是免费的:

  • 在Linux/UNIX上,您可以调用brk()并编写自己的内存分配器.
  • 在每个系统上,您可以使用固定大小的数组作为内存源编写自己的分配器.
  • 我不知道替代品会直接购买malloc/free.他们是有原因的.
  • 返回要在外面使用的局部变量很简单但是错误并且不起作用.

  • "你可以避免使用malloc而不是免费"会产生一个非常糟糕的双关语:D (21认同)

Ken*_*oom 6

您只有两个可用于存储节点的内存空间,而这些是rootnewtemp.将新节点分配给newtemp旧节点时,不再存在.

假设您5在第一次循环迭代之前输入了scanf处的数字,您可以:

5 -> NULL
Run Code Online (Sandbox Code Playgroud)

循环的第一次迭代后,你有

5 -> 4 -> NULL
Run Code Online (Sandbox Code Playgroud)

在循环的第二次迭代之后,你有

5 -> 3 -> NULL
Run Code Online (Sandbox Code Playgroud)

(包含的节点4已被包含的节点完全替换3).

唯一的解决方案是使用malloc,并getnode返回一个node*.


Sev*_*yev 6

您可以静态声明节点结构数组并从该数组中选择新节点.但是,你会实现一个蹩脚,可悲的专业自定义分配器.并且可用节点的最大数量将是该阵列的大小.

或者,您可以使用递归作为分配机制,并对递归堆栈底部的列表执行操作.

这两种方法大致相同.

  • +1实际呈现有效的方法来执行此操作 (4认同)

小智 6

当然,您可以在没有动态内存分配的情况下构建链接列表或任何其他数据结构。但是,无论您多么努力,都无法建立不分配任何内存的内存。

选择:

创建一个全局或静态内存池,您可以在其中放置对象,模仿堆/ malloc / free。FreeRTOS做类似的事情。在这种情况下,自程序开始以来,您将静态分配一个大内存块并将负责对其进行管理,在需要新节点时返回正确的指针,并将该内存标记为已使用。

PS:我不会质疑您为什么要避免使用malloc。我认为你有充分的理由。

在程序中,在第20行中:

     node newtemp,root,temp; 
Run Code Online (Sandbox Code Playgroud)

您正在分配三个节点,其中之一是“ newtemp”。然后,您在第28行进行操作:

     newtemp=getnode(i); 
Run Code Online (Sandbox Code Playgroud)

它只是将返回节点的内容复制到旧的“ newnode”上(有争议,不是吗?)

所以,您只需做以下事情:

     temp.next=&newtemp; 
Run Code Online (Sandbox Code Playgroud)

设置一个指针,该指针最初从“ root.next”到您的“ newnode”。

     if(root.next==NULL) 
Run Code Online (Sandbox Code Playgroud)

第一次通过时将为“ NULL”,但随后仅替换相同的内容。

    temp=*(temp.next); 
     { 
        root=temp; 
     } 
Run Code Online (Sandbox Code Playgroud)

还是数据从单个分配的对象“ *(temp.next)” 复制到另一个“ temp”。它不会创建任何新节点。

如果您这样做,它将起作用:

#include <stdio.h>

typedef struct node 
{ 
    int i; 
    struct node *next; 
}
    node; 

#define MAX_NODES   10

node    *create_node( int a )
{ 
    // Memory space to put your nodes. Note that is is just a MAX_NODES * sizeof( node ) memory array.
    static node node_pool[ MAX_NODES ];
    static int  next_node = 0;

    printf( "[node  *create_node( int a )]\r\tnext_node = %d; i = %d\n", next_node, a );
    if ( next_node >= MAX_NODES )
    {
        printf( "Out of memory!\n" );
        return ( node * )NULL;
    }

    node    *n = &( node_pool[ next_node++ ] );

    n->i = a;
    n->next = NULL;

    return n; 
} 

int main( )
{ 
    int i; 
    node    *newtemp, *root, *temp; 

    root = create_node( 0 ); 
    temp = root; 

    for ( i = 1; ( newtemp = create_node( i ) ) && i < MAX_NODES; ++i )
    { 
        temp->next = newtemp; 

        if ( newtemp )
        {
            printf( "temp->i = %d\n", temp->i );
            printf( "temp->next->i = %d\n", temp->next->i );
            temp = temp->next;
        }
    }


    for ( temp = root; temp != NULL; temp = temp->next )
        printf( " %d ", temp->i );

    return  0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

    $ gcc -Wall -o list_no_malloc list_no_malloc.c 

$ ./list_no_malloc
[node   next_node = 0; i = 0)]
[node   next_node = 1; i = 1)]
temp->i = 0
temp->next->i = 1
[node   next_node = 2; i = 2)]
temp->i = 1
temp->next->i = 2
[node   next_node = 3; i = 3)]
temp->i = 2
temp->next->i = 3
[node   next_node = 4; i = 4)]
temp->i = 3
temp->next->i = 4
[node   next_node = 5; i = 5)]
temp->i = 4
temp->next->i = 5
[node   next_node = 6; i = 6)]
temp->i = 5
temp->next->i = 6
[node   next_node = 7; i = 7)]
temp->i = 6
temp->next->i = 7
[node   next_node = 8; i = 8)]
temp->i = 7
temp->next->i = 8
[node   next_node = 9; i = 9)]
temp->i = 8
temp->next->i = 9
[node   next_node = 10; i = 10
Out of memory!
 0  1  2  3  4  5  6  7  8  9 
Run Code Online (Sandbox Code Playgroud)

  • 两个词——“自定义分配器”——就足够了。这在字母上而不是在精神上避免了 malloc() 。 (3认同)