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

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 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]; 

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

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

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

 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); 
 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; }; 

现在我们添加我们的包和配置 – > m:

  #include  #include  // your config->m const int m = 10 ; 

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

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

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

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

并且malloc up 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) ,因为每个节点都是(在数组中)它在列表中的下一个节点之后的节点(列表是“反向”数组)。

我们将它转​​换为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),