2016-11-07 6 views
0

私は古典的な数値型では表現できない数値の素数分解をしようとしています。 その大きな数字を文字列として読み取った後、10^6より小さいすべての素数で割ります(事前に生成されています)。プロセスでは、メモリの動的割り当てを使用します。私のコードを完成させた後、私はvalgrindの出力をチェックして、同じことが原因であると思われるいくつかのエラーを見つけました。私のコードで何が間違っているのか分かりません。私は研究を行いましたが、多くの人が同じエラーに遭遇しましたが、解決策は私の問題には当てはまりませんでした。 私はすべてのアドバイスのために幸せになるでしょう。ここでvalgrindでサイズ1の書き込み/読み取りが無効です。答えが見つかりません。

は(私の問題のための実質的でない機能なし)私のコードです:

long* primeArray; 
long endDiv = 101; 
long r; 
long length; 
char *division(char dividend[],long divisor){ 
    char *multiplier = malloc(sizeof(char*)*endDiv); 
    long temp=0; 
    int i=0; 
    int j=0; 
    while(dividend[i]){ 
     temp = temp*10 + (dividend[i] - 48); 
     if(temp<divisor){ 
      multiplier[j++] = 48; 
     } 
     else{ 
      multiplier[j++] = (temp/divisor) + 48; 
      temp = temp % divisor; 
     } 
     i++; 
    } 
    multiplier[j] = '\0'; 
    length = j; 
    r = temp; 
    return multiplier; 
} 
void doDecomposition(char* divident){ 
    long* primeDec = (long*)malloc(endDiv* sizeof(long*)); 
    int counter = 0; 
    char * multiplier; 
    for(int i = 0;i<endPrime-1;i++){ 
      multiplier = division(divident, primeArray[i]); 
      if(r == 0){ 
       free(divident);     
       divident = multiplier; 
       primeDec[counter] = primeArray[i]; 
       i = -1; 
       counter++; 
      }else{ 
       int f = 0; 
       for(int a = length-1;a>0;a--){ 
        if(multiplier[a] != '0'){ 
         f = 1; 
         break; 
        } 
       } 
       free(multiplier); 
       if(f==0){ 
        break; 
       } 
      } 
    } 
    printCount(primeDec, counter); 
    free(primeDec); 
    free(divident); 
} 
int main(int argc, char *argv[]) 
{ 
    char* divident = malloc(endDiv*sizeof(char*)); 
    genPrime(1000000); 
    if(divident == NULL){ 
     exit(666); 
    } 
    while(fscanf(stdin, "%s", divident) == 1){ 
     if(divident[0] == '0' && divident[1]=='\0'){ 
      exit(0); 
     } 
     else if(divident[0] == '1' && divident[1]=='\0'){ 
      fprintf(stdout, "Prime decomposition of 1 is:\n1\n"); 
     } 
     else{ 
      checkDivident(divident); 
      fprintf(stdout,"Prime decomposition of %s is:\n", divident); 
      doDecomposition(divident); 
     } 
    } 
    free(divident); 
    return 0; 
} 

そして、ここでは私のvalgrindの出力です:行番号の

==17523== Invalid write of size 1 
==17523== at 0x51A0695: _IO_vfscanf (vfscanf.c:1107) 
==17523== by 0x51AE8E8: __isoc99_fscanf (isoc99_fscanf.c:34) 
==17523== by 0x40126F: main (main.c:185) 
==17523== Address 0x550c040 is 0 bytes inside a block of size 808 free'd 
==17523== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x401128: doDecomposition (main.c:161) 
==17523== by 0x401252: main (main.c:195) 
==17523== Block was alloc'd at 
==17523== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x400C8A: division (main.c:73) 
==17523== by 0x401080: doDecomposition (main.c:145) 
==17523== by 0x401252: main (main.c:195) 
==17523== 
==17523== Invalid write of size 1 
==17523== at 0x51A0752: _IO_vfscanf (vfscanf.c:1192) 
==17523== by 0x51AE8E8: __isoc99_fscanf (isoc99_fscanf.c:34) 
==17523== by 0x40126F: main (main.c:185) 
==17523== Address 0x550c041 is 1 bytes inside a block of size 808 free'd 
==17523== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x401128: doDecomposition (main.c:161) 
==17523== by 0x401252: main (main.c:195) 
==17523== Block was alloc'd at 
==17523== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x400C8A: division (main.c:73) 
==17523== by 0x401080: doDecomposition (main.c:145) 
==17523== by 0x401252: main (main.c:195) 
==17523== 
==17523== Invalid read of size 1 
==17523== at 0x4011C4: main (main.c:186) 
==17523== Address 0x550c040 is 0 bytes inside a block of size 808 free'd 
==17523== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x401128: doDecomposition (main.c:161) 
==17523== by 0x401252: main (main.c:195) 
==17523== Block was alloc'd at 
==17523== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x400C8A: division (main.c:73) 
==17523== by 0x401080: doDecomposition (main.c:145) 
==17523== by 0x401252: main (main.c:195) 
==17523== 
==17523== Invalid read of size 1 
==17523== at 0x4011D3: main (main.c:186) 
==17523== Address 0x550c041 is 1 bytes inside a block of size 808 free'd 
==17523== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x401128: doDecomposition (main.c:161) 
==17523== by 0x401252: main (main.c:195) 
==17523== Block was alloc'd at 
==17523== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==17523== by 0x400C8A: division (main.c:73) 
==17523== by 0x401080: doDecomposition (main.c:145) 
==17523== by 0x401252: main (main.c:195) 
==17523== 
==17523== 
==17523== HEAP SUMMARY: 
==17523==  in use at exit: 627,992 bytes in 1 blocks 
==17523== total heap usage: 1,252,545 allocs, 1,252,544 frees, 1,504,746,312 bytes allocated 
==17523== 
==17523== LEAK SUMMARY: 
==17523== definitely lost: 0 bytes in 0 blocks 
==17523== indirectly lost: 0 bytes in 0 blocks 
==17523==  possibly lost: 0 bytes in 0 blocks 
==17523== still reachable: 627,992 bytes in 1 blocks 
==17523==   suppressed: 0 bytes in 0 blocks 
==17523== Reachable blocks (those to which a pointer was found) are not shown. 
==17523== To see them, rerun with: --leak-check=full --show-leak-kinds=all 
==17523== 
==17523== For counts of detected and suppressed errors, rerun with: -v 
==17523== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0) 

情報:

185: while(fscanf(stdin, "%s", divident) == 1){ 
161: free(multiplier); 
195: doDecomposition(divident); 
73: char *multiplier = malloc(sizeof(char*)*endDiv); 
145: multiplier = division(divident, primeArray[i]); 

すべてのおかげで、私は少しでも手がかりになってうれしいです!

+0

私が見ることができる最初のことは、 'doDecomposition'無料の' divident'であり、メインの最後の行もそれを解放します。だから私は主なものは必要ではなく、間違っていると思います。 – LPs

+0

エラーの原因となる入力( 'stdin')は何ですか?あなたの質問を改善するために、あなたはこれを読んでみたいでしょう:[mcve] – anatolyg

+4

あなたのmallocはすべて間違っています。あなたが使用しようとしているパターンは 'T * p =(T *)malloc(N * sizeof(T));'ですが、 'sizeof(T *)'を使っています。実際、エラーの起こりにくいパターンは 'T * p = malloc(N * sizeof * p);'であり、 'T'の繰り返しを避けます。 –

答えて

3

問題は、doDecomposition機能であなたの部下を解放することです。 したがって、条件if(r == 0)が真の場合、次のループではmainで実行し、所有していないメモリに書き込もうとします。あなたのループの中で、あなたがプログラムの最後にそれを解放すれば、なぜあなたは自由にしたいのですか?

もう1つの質問は、なぜif(divident[0] == '0' && divident[1]=='\0')ですか? strcmp男を読んで、それが読みやすく、かつ使いやすい;「、あなたに

最後のものは、ときにmalloc、私はあなたが私のタイプを変更したい場合ので、それは、int *i = malloc(sizeof(int*));よりint *i = malloc(sizeof(*i));を作るために、より良いことだと思います)すべての割り当てを正しいタイプで変更する必要があります。あなたが小さなプログラムを持っているときには問題ではありませんが、大きなプログラムでは難しくなります。

+0

ありがとうございました。以前のコメントに合わせてコードを編集しましたが、これは正しいソリューションです。私は以前これを気付かなかった。私はまた、より良いCコードを書くために私の将来の仕事であなたの他のヒントを適用しようとします。私はあなたが私にこの問題を解決するのを手伝ってくれて本当にうれしく思います。 – shade254

関連する問題