2017-07-12 7 views
0

関数呼び出しの後、元の配列に問題が発生します数字。すべてが正常に動作している場合 は、だから私は、最初の「内部」ヘッダファイル」ウィッヒが正常に動作しますから、配列の要素を印刷し、テストします。それから私は、ヘッダファイルを含むプログラムでは、ヘッダファイルの外からそれらを印刷しようとしたが、それは働いていないと、プログラムはわずか数の要素を印刷した後に停止します。 この不正な動作はなぜですか?そして、私はこれをどうやって正しい方法で行うことができますか? ありがとうございました。ヘッダファイルは、私は私がしたいことは首相の決定された数と配列を埋めるために、このヘッダファイルで定義された関数generate_primes()を呼び出すことです primes.hというヘッダーファイルを作成し

ヘッダファイル:

int generate_primes(const unsigned long long n, unsigned long long*prime) 
{ 

    try 
     { 
      prime = new unsigned long long[n]; 
     } 
    catch(const std::bad_alloc&e) { 
     std::cerr << e.what(); 
     exit(EXIT_FAILURE); 
    } 

    prime[0] = 2, prime[1] = 3, prime[2] = 5; 

    unsigned long long p; 
    unsigned long long index = 3; 

    for (p = 7; index < n; p += 2) 
     { 
      short isPrime = 1; 
      unsigned long long test_limit = (unsigned long long) sqrt(p); 

      for (int i = 1; prime[i] <= test_limit && i < index; i++) 
       { 
        if (!(p%prime[i])) 
         { 
          isPrime = 0; 
          break; 
         } 
       } 
      if (isPrime) prime[index++] = p; 
     } 

    //everything works fine when I print from inside the header file 
    /*for (int i = 0; i < n; i++) 
     { 
     if (i && i % 7 == 0) std::cout << '\n'; 
     std::cout << prime[i] << "\t\t"; 
     } 
    */ 
    return 1; 
} 

私のプログラム:

#include <iostream> 
#include <cmath> 
#include <vector> 
#include <new> 
#include <cstdlib> 
#include "primes.h" 

int main(){ 
    unsigned long long n = 100;//example 
    unsigned long long *prime; 
    generate_primes(n, prime); 

    //but printing from here causes problems 
    //isn't the array now filled after calling the above function ? 
    for (unsigned long long i = 0; i < n; i++) 
     { 
      if (i && i % 5 == 0) std::cout<< '\n'; 
      std::cout << prime[i] << "\t"; 
     } 

    return 0; 
} 
+1

は、ヘッダファイルに関数定義を入れないでください。 – Barmar

+1

インデントは、これを間違って無視するべきではありません。 – tadman

+1

あなたのプログラムの実際の出力は? –

答えて

2

問題は、パラメータprimeではなく、参照によって、値によって渡されることです。 generate_primeが割り当てられたときにそう:

prime = new unsigned long long[n]; 

をこれは、ローカル変数primeではなく、呼び出し側の変数に割り当てます。代入がmain()に表示されるように、パラメータを参照渡しで渡す必要があります。

int generate_primes(const unsigned long long n, unsigned long long*&prime) 
+0

一般的には、配列全体を呼び出し側で割り当て、そこからその配列の存続時間を管理するほうがよいでしょう。今、アレイの誰がどのように世話をするべきかは不明です。それでは、あなたはそのような問題さえ持たないでしょう。 –

+1

@ K.Kirszさらに、 'std :: vector'を使う方が良いでしょう。 – Barmar

+0

@ K.Kirsz _best方法は、 'std :: vector'参照パラメータを使うことです。 – user0042

0

ヘッダファイルではありません、それはコードの束です。そのコードを分離したい場合は別のファイル.cppにあるはずです。

関連する.hは次のようになります。あなたは、両方の.cppファイルをコンパイルする必要があると思い、あなたのアプリケーションを構築するには

#include "generate_primes.h" 

int generate_primes(const unsigned long long n, unsigned long long*prime) { 
    // (function body) 
} 

#include <cmath> 
#include <vector> 
#include <new> 

int generate_primes(const unsigned long long n, unsigned long long*prime); 

を次に、あなたがgenerate_primes.cppまたはそれのような何かを持っていると思いますそれらを必要なライブラリとリンクさせることができます。

+0

あなたはそうです、そうではありません。私がやったことは、それをたくさん使っているので、コードのこの部分を分けておくことです。それが必要なときはいつでもそれを呼び出すことができます。 – Younes

+0

これはまさにあなたのコードを複数の '.cpp'ファイルに分解し、その中の関数を持つ' .cpp'のそれぞれに、それらが何であるかを定義する '.h'ファイルがあります。これはコンパイルを複雑にしますが、あなたは 'Makefile'にコミットする必要があります。良いコンパイラセットアップでは、再コンパイルが必要な '.cpp'ファイルだけがルーチンビルド時にコンパイルされ、開発が大幅に高速化されます。 '.h'ファイルにあるように、関数シグネチャが変更されていなくてもカスケード再構築が行われます。 – tadman

0

初期化されていないポインタprimeの値は、generate_primesの呼び出しの引数です。そこでは評価されませんが、パラメータは新しい(ローカル)値を割り当てました。したがって、このメソッド内では、Arrayはアクセス可能です。しかし、新しい値は返されないので、mainではプライムの値は変更されません。

また、あなたは、n unsingnedからの長い長いコンパイラのtehのために小さいタイプに変更する必要があります。

つの可能な解決策: それはアレイ

unsigned long long *prime generate_primes(const unsigned long n) 

Bのアドレスを返すようにA)generate_primeを変更する)方法

int generate_primes(const unsigned long n, unsigned long long **prime) 
{ 

    try 
    { 
     *prime = new unsigned long long[n]; 
    } catch (const std::bad_alloc &e) { 
    // your code 

の引数としてポインタのアドレスを与えますそして

int main(){ 
    unsigned long n = 100;//example 
    unsigned long long *prime; 
    generate_primes(n, &prime); 

    // your Code 

    delete[] prime; // free memeory 
    return 0; 
} 
+0

ありがとうございます。私は試みました:int generate_primes(const unsigned long long n、unsigned long long *&prime)同じです。 – Younes

関連する問題