【问题标题】:How to create dynamic matrix of structs c?如何创建结构c的动态矩阵?
【发布时间】:2015-03-19 22:05:51
【问题描述】:

我在制作结构的动态矩阵时遇到了一些麻烦。对于动态矩阵,我的意思不是固定数量的列或行。我有固定数量的列(26 个字母),但我希望每列中的行数改变。

这就是我到目前为止所做的......

struct cliente {
   char nome[9];
   struct cliente* next;
};

typedef struct cliente *ClienteSing;
typedef ClienteSing* Cliente[26];

//I'm allocating memory for the matrix. r is an array that tells me the number of lines for a column.
void initArrayCliente (Cliente a, int* r){
   int i=0;
   for(i=0;i<26;i++)
      a[i]=(ClienteSing) calloc (r[i],sizeof(struct cliente));
}

//I'm implementing a hash, so in case of collision, i make a linked list from a position in the matrix. This function puts a client i want to insert, in the correct position in case of collision.
void ultimoRamo (ClienteSing a, ClienteSing b){
   ClienteSing temp;
   temp=a;
   while (temp->next!=NULL)
      temp=temp->next;
   temp->next=b;
}

//I create a client b from a str that contains the client name. In case that the position in the matrix is set to null(doesn't have cliente) i insert b there. Otherwise, i will use the previous function to create a linked list from that position. indice is the position i want to insert in to. It's a value generated by my hash 
void insere(Cliente a, char* str, int indice){

   ClienteSing b;
   b= (ClienteSing) malloc (sizeof(struct cliente));
   strcpy (b->nome, str);
   b->next=NULL;

   if (a[str[0]-'A'][indice]==NULL)
   {
      a[str[0]-'A'][indice]=b;
      printf("Livre\n");
   }
   else {
      ultimoRamo(a[str[0]-'A'][indice],b);  
      printf("Colisão\n");
   }
}

我可以毫无问题地编译它,它插入得很好并且不会给我任何分段错误...但是当我打印矩阵中的内容时,它会给我垃圾...如果我打印同一个单元格在插入函数中,它可以毫无问题地打印...你能帮我弄清楚我做错了什么吗?

【问题讨论】:

  • 一些有风险的业务:您不检查 str[0] 是否确实是大写字母。你也不检查strlen(str) &lt; sizeof b-&gt;nome。贴出打印功能的代码,问题可能就藏在那里了。
  • @chqrlie 我的 str 总是大小为 6。例如,格式为 AA111。我在这段代码之外检查了这个:) 这是我用于打印paste2.org/DZfE6LhO 的代码正如我所说,我没有任何分段错误,即使在打印中也是如此。它只是打印垃圾。
  • 您假设str 始终是6 并以大写字母开头,但要使您的代码能够适应迟早发生的错误输入。下一个程序员不会知道你做了什么假设。你甚至可能成为下一个程序员……
  • 我是 100% 的舒尔朋友 :) 我阅读并验证了这些文字。我将字母转换为大写,只有当它们是那种格式时,我才让它们传递给这个函数。如果他们不遵守此规则,他们将被淘汰出计划 :)
  • 然后在这个函数之前写一个明确的注释来解释为什么你不检查参数的完整性。这样读者(和潜在的维护者)就会知道。

标签: c memory dynamic matrix


【解决方案1】:

您的打印代码有误:

for(z=0;z<26;z++)
    for(t=0;t<arrayCliente[z];t++)
        if(a[z][t].nome==NULL){printf("Fodeu-se");}
        else printf("%s",a[z][t].nome);

a[z][t].nomechar 的数组,而不是指向char 的指针。因此,如果a[z][t] 本身就是NULL,那么它只是NULL,并且只是偶然的,因为nome 是这个结构的第一个成员。

此外,您分配和操作结构数组,而不是指向结构的指针数组。比较a[str[0]-'A'][indice]==NULL 是没有意义的。

我建议你去掉指针,更重要的是去掉数组typedefs,这是一个非常令人困惑的 C 结构。然后使矩阵成为指向结构指针数组的指针数组。

【讨论】:

  • 所以删除 typedefs,然后创建一个 ClientSing。然后让 ClientSing **a; malloc 的列数,以及每个 c malloc 的行数?是这样吗?
  • 使a 成为指向struct ciente 结构的指针数组的指针数组。 struct cliente *a[26]; 其中a[i] = calloc(r[i], sizeof(struct cliente*));
  • 对于一个严格遵守的程序,您应该将伪矩阵中的每个指针初始化为NULL,因为空指针不一定都是零位。在实践中,我从未遇到过所有位为零都不是NULL 指针的实际CPU。但是外面的人可能有一个备用的 DS9K 模拟器来证实我的观点。
  • 我会试一试。我会告诉你进展如何。
猜你喜欢
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 2021-03-03
  • 2020-03-03
  • 1970-01-01
相关资源
最近更新 更多