0

我一直在重写我的一些函数以返回 int 而不是结构,这样我就可以做到这一点

if ( function(&struct1,vars) != 0 ) 
 { 
  // die and give error 
 }

代替:

结构 = 函数(变量);

然而,我在这里遗漏了一些概念,因为每当我尝试在主结构中访问我的结构的值时,我都没有得到在函数中分配给它的值。如果有人可以向我解释我的记忆/变量到底发生了什么(我会写下我认为会发生什么)以及为什么它不起作用,我将不胜感激。

主要(缩短):

int  main (int argc, char *argv[]) {   
  arguments args;   
  data data;  
  scan scans;   
  printf("Value at start %i\n",scans.number);
  if (scan_extractor(&args,&scans) != 0) // Pass the reference of the struct to scan_extractor (while still being un-initilizaed, something I don't quite grasp).
   {
     printf("Error in argument reader\n");
     exit(0);
   } else { 
     printf("Main thinks %i scans\n",scans.number); 
   } 
  return(0); 
}

功能(scan_extractor):

int
scan_extractor(arguments* args, scan* scans)
{
  FILE* fr;
  int counter = 0;
  fr = fopen(args->scans,"r");
  scans = calloc(MAX,sizeof(scan)); // Allocate memory to store multiple instances of the scan object
  while (fgets(mzML_buffer,MAX_BUFFER,fr) != NULL)
   {
    (scans+counter)->id = atoi(mzML_buffer); // Modify the global version of scans
    counter++;
   }
  scans->number = counter;
  printf("Function read %i scans\n",scans->number);
  return(0);
}

读取的文件包含 1 行包含值 1

我得到的输出是:

Value at start 32767
Function read 1 scans
Main thinks 32767 scans

为什么这让我发疯是因为可以使用类似的语法从 main 访问包含输入参数的几乎相同的代码块(仅结构参数的 char* 值与结构扫描的 int 值)。

4

2 回答 2

1
scan_extractor(arguments* args, scan* scans)
scans = calloc(MAX,sizeof(scan));

您正在为正在传递的指针的副本分配内存。为了能够为函数内部的指针分配内存。您需要通过引用传递指针:

scan_extractor(arguments* args, scan** scans)
*scans = calloc(MAX,sizeof(scan));

回头一想。你的程序没有意义。你混合了两个概念。
您在本地存储上分配一个scan对象并将其地址传递给函数。在函数内部,您将动态内存分配给指针本地的函数,该指针先前指向传递的对象。这只会泄漏内存,而您的基于堆栈的scan对象永远不会被填充

基本上,您只需要传递对象的地址并使用该对象。它已经分配,​​无需在函数内部进行分配。

scan scans; 
if (scan_extractor(&args,&scans)

scan_extractor(arguments* args, scan* scans)
scans->number = counter;
于 2013-01-23T14:30:38.450 回答
1

您需要第二级间接才能返回分配的单元。函数 scan_extractor 应该如下所示:

int scan_extractor(arguments* args, scan** scans)
{
  FILE* fr;
  int counter = 0;
  fr= fopen(args->scans,"r");
  *scans = calloc(MAX,sizeof(scan));
  while (fgets(mzML_buffer,MAX_BUFFER,fr) != NULL)
   {
    ((*scans)[counter]).id = atoi(mzML_buffer); // Modify the global version of scans
    counter++;
   }
  (*scans)->number = counter;
  printf("Function read %i scans\n",(*scans)->number);
  return(0);
}

看这段代码不知何故告诉我这些行(*scans)->number = counter;printf("Function read %i scans\n",(*scans)->number);错误都是错误的,但在不知道扫描结构的情况下我无法判断这一点。我想我可以猜到意图(存储扫描次数)。我建议通过稍微修改的方法来解决这个问题:

typedef struct scanlist {
    unsigned int count;
    scan *scans;
}scanlist;

...

int scan_extractor(arguments* args, scanlist* scans)
{
  scans->scans = calloc(MAX,sizeof(scan));
  ...
  while (...) {
    scans->scans[counter].id = ...
  }
  ...
  scans->count = counter;

否则,您会浪费内存,每次扫描都不需要数字字段。

于 2013-01-23T14:43:27.157 回答