指向结构数组和获取内存的指针

时间:2009-04-15 02:35:50

标签: c pointers

link是指向节点的指针

typedef struct node * link;

在main()中,我有以下代码(config-> m只是一些整数):

// array of pointers to structs
link heads[config->m]; 

// make memory for head nodes
for(i = 0; i < config->m; i++)
  heads[i] = malloc(sizeof(struct node));

代码有效(很棒)。 但是有没有办法可以在没有循环的情况下分配config->m个内存?我试过了

link heads[config->m];
heads = malloc(sizeof(struct node) * config->m);

但我友好的邻居编译器告诉我incompatible types in assignment

我知道我可以使用

struct node heads[config->m];

但我想用指针来做这些事情。

和往常一样,有人会问我这是否是家庭作业的一部分,答案是肯定的(有点)。但是这个特殊的代码块与实际的赋值没有任何关系;这是我自己的启蒙。但感谢您的提问:|

2 个答案:

答案 0 :(得分:3)

不,你需要循环。你的头数组本质上是一个二维数组。您至少需要两次分配。第一个是指针数组:

link * heads = (link*)malloc (config->m * sizeof (link));

第二个是head数组的每个成员指向的内存:

link buf = (link)malloc(sizeof(struct node) * config->m);
for(i = 0; i < config->m; i++)
    heads[i] = &buf[i];

然后取消分配:

free(heads);
free(buf);

答案 1 :(得分:1)

link heads[config->m]; 
link buffer = malloc(sizeof(struct node) * config->m);

for(i = 0; i < config->m; i++)
  heads[i] = &buffer[i];

....
free(buffer);

编辑时: 实际上,您不需要heads。首先,让我们摆脱link,因为(参见Cannonade的回答中的评论)它只是混淆了这个问题。

让我们假设一个struct节点是一个侵入式链表中的一个节点,如下所示:

      struct node {
        int val;
        int filler[10]; // this is pure filler, to make node big
        struct node* next;
      };

现在我们添加我们的include和config-&gt; m:

  #include <stdio.h>
  #include <stdlib.h>
  // your config->m
  const int m = 10 ; 

在main()中我们打印一个节点的大小:

  int main() {

     printf( "sizeof( struct node ) = %i\n", sizeof( struct node) );

现在我们声明一个指向node的指针:

     // na is a node pointer
     struct node* na;

并选择 m 节点。 malloc返回数组的地址,这也是数组中第一个节点的地址。我们将na设置为返回的地址malloc:

      na = malloc(sizeof(struct node) * m);

现在我们将使用na,一个指针,就像它是一个数组一样。这是有效的,因为C将array[offset]定义为*(array + offset * sizeof(element))

     int i;
     // we give the first node a val of zero
     na[0].val = 0;
     // and a null next pointer
     na[0].next = 0 ;

现在我们将走向数组的其余部分并将每个节点设置在数组中的 PREVIOUS 节点旁边:

     for(i = 1; i < m; i++) {
        na[i].val = i ;
        // na[ offset ] is *(na + offset)
        // we don't want to dereference, 
        // we want the address, so we use the 
        // address-of operator ("&")
        na[i].next = &na[ i - 1 ];
     }

我们的头是数组na[ m - 1]中的最后一个节点。列表中的每个next都是数组中的前一个节点。同样,如果我们想要指针而不是指向的指针,我们使用address-of运算符:

     struct node* current = &na[ m - 1 ];

我们将打印每个节点的地址。它应该是其next节点指针+ sizeof( struct node)的地址,因为每个节点都是(在数组中)它在列表中的下一个节点之后的节点(列表是“反向”数组)。 / p>

我们将它转​​换为char *以获得字节结果。如果我们不进行投射,我们会以truct node*为单位得到结果(应该始终为1)。

     while( current ) {
        printf( "val %i, address of current %p, ", current->val, current) ;
        printf( " address of current->next %p, ", current->next ) ;
        if( current->next ) {
           printf( " distance from next: ");
           printf( "in bytes %i, ", 
              ( (char*) current)  - (char*) current->next ) ;
           printf( " in struct nodes %i", current  - current->next ) ;
        }
        printf( "\n" );
        current = current->next;   
     }

     return 0;
  }

在我的系统上,提供此输出:

  sizeof( struct node ) = 48
  val 9, address of current 0x804a1b8,  address of current->next 0x804a188,  distance from next: in bytes 48,  in struct nodes 1
  val 8, address of current 0x804a188,  address of current->next 0x804a158,  distance from next: in bytes 48,  in struct nodes 1
  val 7, address of current 0x804a158,  address of current->next 0x804a128,  distance from next: in bytes 48,  in struct nodes 1
  val 6, address of current 0x804a128,  address of current->next 0x804a0f8,  distance from next: in bytes 48,  in struct nodes 1
  val 5, address of current 0x804a0f8,  address of current->next 0x804a0c8,  distance from next: in bytes 48,  in struct nodes 1
  val 4, address of current 0x804a0c8,  address of current->next 0x804a098,  distance from next: in bytes 48,  in struct nodes 1
  val 3, address of current 0x804a098,  address of current->next 0x804a068,  distance from next: in bytes 48,  in struct nodes 1
  val 2, address of current 0x804a068,  address of current->next 0x804a038,  distance from next: in bytes 48,  in struct nodes 1
  val 1, address of current 0x804a038,  address of current->next 0x804a008,  distance from next: in bytes 48,  in struct nodes 1
  val 0, address of current 0x804a008,  address of current->next (nil),