无法在 c 中传递正确的动态结构数组

Cant pass a correct Dynamic array of structs in c

我正在为学校做一个项目,但我无法将结构的动态数组传递给 c 中的另一个函数。该函数只是应该检查结构的一个元素,如果数组的该元素等于当前元素,则 return 已经添加。我在声明接受 calloc 数组的函数时也遇到了麻烦。任何帮助,将不胜感激!我整晚都在寻找解决方案。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
struct EDGETAG;
typedef struct
     {
      char c;
      bool isVisited;
      struct EDGETAG* p;
     } VERTEX;

typedef struct EDGE
    {
    VERTEX* v;
    struct EDGETAG* q;
    } EDGE;

int main(int argc, char* argv[])
   {
    int a;
    struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
    char s;
    int count = 0;
    FILE* input = fopen(argv[1],"r");
    while((a = fgetc(input)) != EOF)
       {
        if(isspace(a)==0)
         {
         s = a;
         printf("%c ",s);
         determiner(s,vert,count);
         count++;            
         }
      }
return 0;
}

和调用函数

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>


typedef struct VERTEX
    {
    char c;
    bool isVisited;
    struct EDGETAG* p;
    } VERTEX;


typedef struct EDGETAG
    {
   VERTEX* v;
    struct EDGETAG* q;
    } EDGE;


void determiner (char a, struct VERTEX *vert, int count)
    {
    int i;
    for(i=0;i < count; i++)
       {
       if(vert[i].c == a)
         {
         printf("%c allready added ",vert[i].c);
         return ;
         }
     else
       {
       VERTEX* new1 = (VERTEX*)malloc(sizeof(VERTEX));
       new1->c = a;
       vert[i] = *new1;
      }
    }
return ;

输入是: 甲乙 BC 前任 CD 交流电 output:A B B B 已添加 C E X C D A C

您实际上从未分配任何顶点。

struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));

注意到 sizeof(VERTEX*) 了吗?您已经为 100 个指向顶点的指针分配了足够的 space!

除了 David Schwartz 指出的问题,determiner 的缩进版本更清楚地显示了另一个问题:

void determiner(char a, struct VERTEX *vert, int count)
{
    int i;
    for (i = 0; i < count; i++)
    {
        if (vert[i].c == a)
        {
            printf("%c allready added ", vert[i].c);
            return;
        }
        else{
            VERTEX* new1 = (VERTEX*)malloc(sizeof(VERTEX));
            new1->c = a;
            vert[i] = *new1;
        }
    }
    return;
}

您当前的代码查看数组的第一个元素,看它是否与 a

匹配
  • 如果匹配,则 returns(好)
  • 如果不匹配,它将用新数据覆盖第一个元素(错误)

然后它循环并对第二个元素等做同样的事情

要解决此问题,请将添加新元素的代码移到检查循环之外。如果检查循环结束,那么它还没有找到,所以可以添加。

现在,您有第二个问题 - 无论 determiner 是否找到匹配,您总是增加 count。您应该将 determiner 更改为 return 一个指示是否添加了项目的值,然后在 main 中使用该值来增加计数。

编辑:另请注意 - 如果您只是将其内容复制到 vert[i],则不需要(或不想)使用 malloc 分配新节点。目前您正在泄漏内存 - 直接更新 vert[i].c 更容易。

您正在调用第一个文件

typedef struct
{
  char c;
  bool isVisited;
  struct EDGETAG* p;
} VERTEX;

稍后下来,你有

struct VERTEX *vert = ...

struct VERTEX 不是第一个文件中的类型。 VERTEX 被定义为一种类型。您应该将结构类型更改为

typedef struct VERTEX // note the VERTEX here
{
  char c;
  bool isVisited;
  struct EDGETAG* p;
} VERTEX;    

这已经在第二个文件中完成了。

作为一般风格指南,您应该在单独的头文件中包含 VERTEXEDGE 的结构声明,并将其包含在两个 .c 文件中。

你的代码有很多问题,但我会在上面的答案中加上我的 2 美分,因为我相信它可能会有帮助:

  1. 正如@David 已经注意到的,您正在实例化一个指针数组:

    // this should be a struct VERTEX**, if you want to
    // have a "pointer to the first pointer to VERTEX"
    struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
    

    但您(很可能)想要实例化一个 VERTEX 数组:

    // you probably want space for 100 x sizeof(VERTEX),
    // so that vert is simply a "pointer to the first VERTEX".
    // ALSO: don't cast the result of calloc/malloc 
    struct VERTEX *vert = calloc(100, sizeof(VERTEX));
    

    vert 不是指向分配数组的第一个 VERTEX 元素的指针。您不需要分配单个 VERTEX 元素,并且 vert 永远不会在您迭代时成为 null,因此您需要自己跟踪 count

  2. count 不应在 main 正文中递增,因为您不知道是否实际添加了该元素。

  3. 你的determiner函数不正确;您似乎在 each 循环迭代中添加了一个新实例。我还会 return 函数实际添加元素时的计数值:

    void determiner (char a, struct VERTEX *vert, int *count)
    {
        for(int i = 0; i < count; i++)
        {
            if (vert[i].c == a)
            {
                printf("%c already added ",vert[i].c);
    
                // no need to increase count
                return;
            }
        }
    
        // if we are here, we didn't find the element,
        // so this is where you actually initialize it
        // and increase count
    
        vert[count]->c = a;
        count++;
    }
    

    调用函数时,将指针传给count,让函数自增:

    determiner(s, vert, &count);
    
  4. 在处理图形时,通常使用链表,即让节点指向其他节点。在这种情况下,您不分配数组,而是分别为每个节点使用 malloc 并向前跳转,直到到达 null。尝试在谷歌上搜索如何在 C 中实现图形的示例,以便更好地了解正确的方法。