0

次のプログラムは、1 から 10 までの素数を出力します。

#include <stdio.h>
int* prime(int x,int y,int* range);

void main()
{
    int *x,s=10;
    int i=0; 
    x=prime(1,10,&s);

    for(i=0;i<s;i++)
    {
        printf("%d\n",x[i]);
    }


}
int* prime(int x,int y,int *range){

    int num[100],i,j,flag,inc=0;

    for(i=x;i<=y;i++)
    {
        flag=1;
        for(j=2;j<=(i/2);j++)
        {
            if(i%j == 0)
                flag=-1;
        } 
        if(flag==1)
        {

            num[inc]=i;
            inc++;
        }

    }
    *range=inc;
    //printf("$$%d$$",*range);
    return num;
}

上記の場合、出力は 1 2 3 5 0 ですが、prime 関数の printf ステートメントのコメントを削除し、通常の printf ステートメントとして与えると、出力は 1 2 3 5 7 になります。ここのバグは何ですか??

私が使用したコンパイラは、Linux プラットフォームの GCC コンパイラです。

4

3 に答える 3

1

スタックに int 配列を割り当てています。したがってreturn num;、範囲外になり、動作が未定義になると、ポインターが無効になり、スタックが破損するためです。

配列を main 内に割り当て、それを main に渡すか、prime()またはmalloc()その中に渡してからprime()返し、main で解放する必要があります。

于 2013-07-31T05:12:18.913 に答える
0

ローカル変数のアドレスをメインに渡しています。それは良い習慣ではありません。ローカル変数のスコープはそのモジュール内です。したがって、配列を素数に直接渡して、結果を直接処理できます。 注:あなたのコードは、プライムにprintfがなくても完全に機能します..未定義の動作。

#include <stdio.h>
void prime(int x,int y,int* range, int * arr);
void main()
{
    int n[10],s=10;
    int i=0; 
    prime(1,10,&s,n);
    for(i=0;i<s;i++)
    {
        printf("%d\n",n[i]);
    }
}
void prime(int x,int y,int *range,int *arr)
{
    int i,j,flag,inc=0;
    for(i=x;i<=y;i++)
    {
        flag=1;
        for(j=2;j<=(i/2);j++)
            if(i%j == 0) flag=-1;
        if(flag==1) *(arr+inc++)=i;
   }
   *range=inc;
}
于 2013-07-31T06:03:28.143 に答える