【问题标题】:array not storing the address of structure数组不存储结构的地址
【发布时间】:2019-03-03 07:43:58
【问题描述】:

我正在尝试使用邻接列表来实现图形,据我所知,如果我创建变量 array 指向 struct adjlistnode 大小为 v*sizeof(struct adjlistnode) 的变量,我可以存储 v @987654324 的地址@type 数组每个索引中的节点

意味着数组的每个索引都将指向 struct adjlistnode 类型的节点,但是当我分配 G->array[i]=NULL 时,它会给我错误

||=== Build: Debug in teeest (compiler: GNU GCC Compiler) ===| C:\Users\Mahi\Desktop\DATA STR\teeest\main.c||In function 'creategraph':| C:\Users\Mahi\Desktop\DATA STR\teeest\main.c|59|error: incompatible types when assigning to type 'struct adjlistnode' from type 'void *'| ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

为什么我不能将 NULL 分配给数组的索引

如果我想访问邻接列表,例如使用与ith 顶点相邻的G->array[i]=第一个节点地址,我应该怎么做,然后如果需要,我将添加另一个节点

struct adjlistnode{
    int dest;
    struct adjlistnode* next;
};
struct graph{
   int V;
   struct adjlistnode* array;
};
struct adjlistnode* getnewnode(int dest){
   struct adjlistnode* newnode =(struct adjlistnode*)malloc(sizeof(struct adjlistnode));
   newnode->dest=dest;
   newnode->next=NULL;
   return newnode;
}
struct graph* creategraph(int v){
   struct graph* G=(struct graph*)malloc(sizeof(struct graph));
   G->V=v;
   G->array=(struct adjlistnode*)malloc(v*sizeof(struct adjlistnode));

   for(int i=0;i<v;i++){
      G->array[i] =NULL;
   }
   return G;

}

【问题讨论】:

  • 因为只有指针可以是NULL。您的 G-&gt;array 不是指针数组
  • 至少在 C 中所有这些强制转换都是无用的。

标签: c arrays pointers data-structures structure


【解决方案1】:

G-&gt;array 的类型为 struct adjlistnode *

但是

G-&gt;array[i] 的类型为 struct adjlistnode

因此您不能将NULLvoid * 类型)分配给G-&gt;array[i] 类型struct adjlistnode

您可能必须将struct graph 中的array 定义为指向指针的指针

struct graph{
   int V;
   struct adjlistnode** array;
};

然后以下应该适合你

struct graph* creategraph(int v){
   struct graph* G=malloc(sizeof(struct graph));
   G->V=v;
   G->array=malloc(v*sizeof(struct adjlistnode*));

   for(int i=0;i<v;i++){
      G->array[i] =NULL;
   }
   return G;

}

** Note1(正如 @alk 在 cmets 中也提到的)在 C 中,至少从 C89 标准开始,malloc 返回 void *void * 可以分配给任何其他指针类型(反之亦然),因此不需要转换 malloc 的返回值。

** Note2(@alk 也指出)malloc 签名是用size_t 类型的参数定义的,而不是int,所以最好稍微修改一下代码并使用正确的类型(阅读comparing int with size_tsize_t vs int in C++ and/or C 了解更多信息)

【讨论】:

  • 再次吹毛求疵:所有ints 都应该是size_ts。
  • @alk,我同意这将是最正确的并且可能防止 signed vs unsigned 错误,但它与 代码审查 区域相关而不是问题本身。但我不介意添加另一个注释。
  • 如果我想通过vas size_t 那么是否需要在我的结构中将int 更改为size_t
  • @david12345 是的,最好与正确的类型对齐。 v 没有理由消极
【解决方案2】:

array 是指向struct adjlistnode 的(单个)指针。所以可以设置为NULL。

 G->array = NULL; //is okay

但它不是一个指针数组,所以你不能访问数组的元素,它们也不能设置为 NULL。

对于动态分配,你应该这样做:

struct graph{
   int V;
   struct adjlistnode** array;
};
struct graph* creategraph(int v){
   struct graph* G = malloc(sizeof(struct graph));
   G->V = v;   
   G->array = malloc(v * sizeof(struct adjlistnode*)); //allocation for an array of v pointers 

   for(int i = 0; i < v; i++){    
      G->array[i] = NULL;
   }
   return G;
}

根据@alk 的建议,最好将v 传递为size_t 而不是int,因为malloc 采用size_t

【讨论】:

  • 像这样:struct adjlistnode* array[10];
  • 好的,先生,我知道了,但是如果我想在上述情况下动态地制作它,您可以在一行中告诉我
  • 更新了动态分配的答案。看看吧。
  • 吹毛求疵:所有ints 都应该是size_ts。
  • 您必须包含 stdlib.h 才能使用 size_t
【解决方案3】:

G-&gt;array[i] 返回*(array + i * sizeof(struct adjlistnode)),好像arraystruct adjlistnode array[]

您所做的是存储 struct 的 v 个对象,但您尝试使用 NULL 初始化它们,就像使用指针一样。

你可能想要的是

struct graph{
   int V;
   struct adjlistnode** array;
};

[...]

G->array=(struct adjlistnode**)malloc(v*sizeof(struct adjlistnode*));

这将使array 成为指向指针数组的指针。

然后G-&gt;array[i] 将返回一个指向结构对象的struct adjlistnode* 指针,然后您可以使用getnewnode() 对其进行初始化。

【讨论】:

  • 至少在 C 中所有这些转换都是无用的。
猜你喜欢
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
相关资源
最近更新 更多