【问题标题】:Returning a bigger type of date from a function with pointer [duplicate]从带有指针的函数返回更大类型的日期[重复]
【发布时间】:2013-01-10 07:14:33
【问题描述】:

可能重复:
How can I get a file’s size in C?

我在 C 语言中有一个函数,它正在从文本文件中读取未知数量的行。 我正在将行中的数据插入到我拥有的struct 中。 每一行我都在用realloc 增加结构的大小。 一切都很好,但是该函数返回这个struct,并且应该插入到程序的“main”struct。从我的思维方式来看,它不应该起作用,而且它也不起作用。 我不知道应该给主struct分配多少空间,然后我尝试比较一个更大的struct

代码很长,但我基本上是这样做的:

int* blah()
{
    int *x;
    x=(int*)malloc(sizeof(int)*3);
    x[0]=1;
    x[1]=2;
    x[3]=3;
    return x;
}

int main()
{
    int *y, *z;
    y=(int*)malloc(sizeof(int)*1);
    z=y;
    z = blah();
 return 0;
}

我怎么知道我应该增加多少y

附言 如果我将 malloc 设为 10 并且文件中有 5 行,那么它就可以正常工作(正如我所料)。

谢谢

编辑: 我正在构建的这个程序是为学校设计的,我得到了读取函数的原型,它只返回结构并获取指向文件的指针。所以我不能发送更多的变量。

编辑 2: 结构:

typedef struct
{
    int x;
    int y;
}POINT;

typedef struct
{
    POINT points[SHAPE_TYPE];
}POLIGON;

typedef struct
{
    POLIGON poly;
    float sides[SHAPE_TYPE];
}RECORD;

读取函数:

RECORD* Read(FILE* F)
{
    RECORD* rec;
    int i=1,j;

    rec = (RECORD*)malloc(PACK*sizeof(RECORD));

        if (rec == NULL) 
        {
                   exit(1); 
        }

    rec[0].poly.points[0].x=0;

    if(F == NULL)
    {
         printf("Could not open a file for reading. Exiting....\n");
         exit(1);
    }


         while (!feof(F))
         {
             if(rec[0].poly.points[0].x==(sizeof(*rec)/sizeof(RECORD)-1))
                rec = (RECORD*)realloc(rec,((sizeof(*rec)/sizeof(RECORD))+PACK)*sizeof(RECORD));

                if (rec == NULL) {
                   exit(1); 
                }

             for(j=0; j<SHAPE_TYPE; j++)
                fscanf(F, "%d,%d,%f,",&rec[i].poly.points[j].x,&rec[i].poly.points[j].y,&rec[i].sides[j]);

             fscanf(F,"\n");

             rec[0].poly.points[0].x=i;

             i++;
         }

      fclose(F);

         return rec;

}

我这样称呼它:

RECORD* rec,p;
FILE *f;

rec = (RECORD*)malloc(PACK*sizeof(RECORD));

p=rec;

f=NULL;
f = fopen("Save.txt", "r");

p = Read(f);

我不能使用全局变量。 PACK - 常量数。我应该用这个数字增加数组。 SHAPE_TYPE - 常量 - 多边形的点数。

在数组的第一个单元格中 -> rec.[0].poly.points[0].x - 这是我应该在数组中保存实际 RECORDs 的数字的地方,所以我从 [1] 开始填充它。

基本上,我要做的是在main() 中创建arrayRECORD,然后使用创建另一个未知大小数组的函数从文件中读取并返回RECORD 的指针(数组)。

简单的方法是将指针数组从主函数发送到函数并且不返回任何内容(void),但我不得不使用这个原型。

【问题讨论】:

  • 不幸的是,您的精简模型中没有结构(还有一些内存泄漏,但我假设您现在更关心扩展,这些泄漏是代码剥离)。如果可能,您能否详细说明main() 中的初始分配(包括结构定义)以及如何在您的阅读器功能中扩展的更多细节?我认为这是可行的,只需将初始分配传递给您的阅读器,然后让根据需要扩展它。
  • 是的,我知道没有结构,我试图在我的原始程序中犯同样的错误(我认为它与结构无关)我知道我没有在我的示例中不要使用free()。结构很少,一个在另一个里面,如果我把所有的都贴在这里,它会很长而且不太可读,所以我试图做同样的动作,但是用这个int
  • 不用担心。从文件中读取的 thing 是否应该与 main 中分配的 thing 进行“比较”(二进制、逐项等)?这是两难境地吗?
  • 为什么需要main中的数据?为什么不只是一个指针?
  • 我正在创建一个主要的结构。我正在调用从文件中读取并构建结构数组并将其返回(作为指针)的函数。我想构造我在 main 中创建的值将是我从函数返回的结构。

标签: c pointers struct


【解决方案1】:

您需要将“旧 z”传递给您的函数,然后使用“realloc” - 您还需要一个“当前计数”,以便知道要扩展到什么大小:

int* blah(int *old, int* count)
{
    int *x;
    *count += 3;     // add three to count, as we are adding three elemnts
    x=realloc(old, sizeof(int)*count);
    if (!x) {
        free(old);   // Prevent leaking the "old" pointer. 
        allocation_failed();   // Do something if this goes wrong!
    }
    x[count-3]=1;
    x[count-2]=2;
    x[count-1]=3;
    return x;
}

int main()
{
    int *z = NULL;   // initialize z to NULL so we can start from "empty".
    int i;
    int count = 0; 
    z = blah(z, &count);
    z = blah(z, &count);
    for(i = 0; i < count; i++)
      printf("%d\n", z[i]);
 return 0;
}

如您所见,我传递了一个指向count 的指针,这样我们就可以将每次调用的计数更新为blah

显然还有许多其他方法可以解决这个问题。

【讨论】:

  • 感谢您的回答。我正在为学校构建的这个程序,我得到了读取函数的原型,它只返回struct,并获取指向文件的指针。所以我不能发送更多变量。
  • 那么我们需要查看更多代码——否则你将不得不以不同的方式解决问题(也就是说,将计数保留在函数之外)——或者你已经被设置一项不可能完成的任务,这似乎不太可能。
  • 如果合适,您可以在 blah 函数内进行所有分配,用特定值标记数组的结尾(因为 '\0' 标记以空字符结尾的字符串的结尾)。你也可以使用全局变量,但这是不好的设计(一般)
  • @MatsPetersson 我偷偷怀疑这是一个灵活数组问题,数组内容是一种结构类型,而头部结构包含包含所有大小信息的数组等。但是因为我们还没有看到任何类似于我们可能永远不会知道的实际结构的东西。
  • 这就是为什么我说我们需要在实际的问题设置中看到更多的代码——我们只能猜测,而猜测并没有那么可靠!
【解决方案2】:

我假设你的意思不是struct,而是struct 的数组(或者你的struct 包含一个行数组),因为我不知道如何在C 中动态增加结构的大小(编辑:见下方 WhozCraig 的评论)。

如有必要,您可以将数组传递给函数并对其进行扩展(使用realloc):

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

int *blah(int *arr, size_t *elem_count, size_t *max_size)
{
    int i;

    for(i = 1; i <= 3; ++i)
    {
        if((*elem_count) == (*max_size)) /* max capacity exceeded */
        {
            int *tmp;
            ++(*max_size);
            tmp = realloc(arr, *max_size * sizeof *arr);
            if(tmp == NULL)
            {
                ;               /* Error handling and cleanup */
            }
            arr = tmp;
        }
        arr[(*elem_count)++] = i;
    }
    return arr;
}

int main(void)
{
    int *arr = NULL;
    size_t count = 0, size = 0, i;
    /* You may also pass an allocated array to `blah' */
    arr = blah(arr, &count, &size);
    if(arr == NULL)
    {
        ;                       /* Error handling and cleanup */
    }

    for(i = 0; i < count; ++i)
        printf("%d\n", arr[i]);

    free(arr);

    exit(EXIT_SUCCESS);
}

您还必须再传递两个指针才能控制数组的容量及其当前包含的项目数。

附言。 C 分配函数不需要显式转换返回值。

【讨论】:

  • 在 C 语言中,您可以通过使用灵活的数组成员(始终必须是 last 成员)来扩展结构。在in this question 中提到了一个这样的具有提议制造技术的示例。它已经存在很长时间了,尽管语法比标准版本有所改变。
【解决方案3】:

嗯,这是realloc 的东西。

我不确定我的所有代码是否都正确编写,但我将realloc 更改为:

        if(((*REC)[0].poly.points[0].x+1) % PACK==0)
        {
            p = (RECORD*)realloc(p,((*REC)[0].poly.points[0].x+1+PACK)*sizeof(RECORD));

                if (p == NULL) 
                {
                   exit(1); 
                }
        }

现在它正在工作..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    相关资源
    最近更新 更多