0

これを実行できるように、関数の一部を構造体ではなくintを返すように書き直しています。

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

それ以外の:

struct = function(vars);

ただし、メインで構造体の値にアクセスしようとすると、関数で構造体に割り当てられた値が取得されないため、ここでいくつかの概念が欠落しています。誰かが私の記憶/変数に正確に何が起こっているのか(私はそれが起こると思うことを書きます)、そしてなぜそれが機能しないのかを私に説明していただければ幸いです。

メイン(短縮):

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

割り当てられたユニットを返すには、第 2 レベルの間接化が必要です。関数 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 に答える
1
scan_extractor(arguments* args, scan* scans)
scans = calloc(MAX,sizeof(scan));

渡されるポインタのコピーにメモリを割り当てています。関数内のポインタにメモリを割り当てることができるようにします。参照によってポインターを渡す必要があります。

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

よく考えてみると。あなたのプログラムは意味がありません。2 つの概念が混在しています。オブジェクトをローカル ストレージに
割り当て、そのアドレスを関数に渡します。scan関数内で、以前に渡されたオブジェクトを指していたポインタに対してローカルな関数に動的メモリを割り当てます。scanスタックベースのオブジェクトが読み込まれない間、これは単にメモリをリークします

基本的に、オブジェクトのアドレスを渡してそのオブジェクトを使用するだけで済みます。すでに割り当てられているため、関数内で割り当てる必要はありません。

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

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