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

时间:2016-06-28 07:08:46

标签: c arrays dynamic struct calloc

我正在为学校的项目工作,我无法将动态数组结构传递给c中的另一个函数。该函数只是检查结构的一个元素,如果该数组的元素等于当前元素,则返回已添加的元素。我也无法声明接受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 ;

输入是: 一个B. B C. E X. C D. 一个C. 输出:A B B B已添加C E X C D A C

4 个答案:

答案 0 :(得分:2)

你永远不会实际分配任何顶点。

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

注意sizeof(VERTEX*)?你已经为100个顶点指针分配了足够的空间!

答案 1 :(得分:0)

除了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

匹配
  • 如果匹配,则返回(好)
  • 如果不匹配,则用新数据(坏)覆盖第一个元素

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

要解决此问题,请移动在检查循环之外添加新元素的代码。如果检查循环结束,则尚未找到,因此可以添加。

现在,您遇到第二个问题 - 无论count是否找到匹配项,您总是会增加determiner。您应该更改determiner以返回指示是否已添加该项目的值,然后在main中使用该值来增加计数。

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

答案 2 :(得分:0)

您正在调用第一个文件

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文件中。

答案 3 :(得分:0)

您的代码存在许多问题,但我会在上面的答案中添加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*));
    

    但是你(很可能)想要实例化一个VERTEXes数组:

    // 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功能不正确;您似乎在每次循环迭代中添加了一个新实例。我还会在实际添加元素时从函数返回计数值:

    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中实现图形的例子,以更好地了解正确的方法。