2016-08-26 15 views
2

私が割り当てたメモリをdinamicallyで解放しないと私のプログラムが動作しますが、解放しようとするとクラッシュします。私はDev-C++で自分のコードを実行していますが、エラーメッセージは役に立ちません。問題がプログラムの動作を停止させました。 問題はコードの最後です。私が自由な部分を取る場合、プログラムは正常に動作します。配列にフリー関数(C)を使用すると、私のプログラムがクラッシュする

5 
2.3 
1.4 8.2 
3.1 2.0 7.7 
5.3 6.1 4.4 1.2 
5.5 6.1 3.0 2.3 4.9 

コード:

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 

int main(void) { 
    int ordem; 
    scanf("%d", &ordem); 
    double **vetor; //apontador para apontador (jagged array) 
    double soma = 0; 
    int elementos; 
    elementos = (ordem*ordem + ordem)/2; 
    vetor = malloc(ordem * sizeof(double*)); //o primeiro endereço do vetor é seu local de memória, que define quantos pointers ele terá (ordem) 
    int n, m; 
    for (n = 0; n < ordem; n++) { 
     *(vetor + n) = malloc(n * sizeof(double)); 
    } 
    for (n = 0; n < ordem; n++) { 
     for (m = 0; m <= n; m++) { 
      scanf("%lf", *(vetor + n) + m); 
      soma = soma + *(*(vetor + n) + m); 
     } 
    } 
    double media = soma/(double) elementos; 
    double aux = 0; 
    for (n = 0; n < ordem; n++) { 
     for (m = 0; m <= n; m++) { 
      aux = aux + pow((media - vetor[n][m]), 2); 
     } 
    } 
    double desvio = sqrt(aux/((double)elementos)); 
    for (n = 0; n < ordem; n++) { 
     for (m = 0; m <= n; m++) { 
      printf("%.12lf ", (vetor[n][m] - media)/desvio); 
     } 
     printf("\n"); 
    } 
    printf("\n%.12lf %.12lf \n", media, desvio); 

    for (n = 0; n < ordem; n++) { 
     free(*(vetor + n)); 
    } 
    free(vetor); 

    return 0; 
} 

そして、それはかなりそれだここではサンプル入力です。私はこれを解決する方法を知らない。私はdeallocと同じ効果があるとは思わない。私は自由にこだわることを好む。私が発見した新しい情報:サンプル入力のために私はフリーで((vetor + 0))、((vetor + 1))、(*(vetor + 2))、何とかこれらの2つに問題があります。

+0

あなたの問題は 'free'は一般的にあなたのコードのどこか他の場所でオーバーランが発生するためです。私は見てみましょう。 –

+3

'malloc(n * sizeof(double));' - これは割り当てループの最初の繰り返しではゼロ割り当てになります。私は 'malloc((n + 1)* sizeof(double));にそれを変更するとは思わない;特にあなたが* m = 0でその場所を読み込んでいるので違いがある。 m <= n'を内部ループのinit /条件​​として使用します。 – WhozCraig

+0

@ DavidC.Rankin あなたはそうです!最初のループには何も割り当てません。それはおそらく問題です。出来た!ありがとう、男! –

答えて

3

変更この:これに

for (n = 0; n < ordem; n++) { 
    *(vetor + n) = malloc(n * sizeof(double)); 
} 

for (n = 0; n < ordem; n++) { 
    *(vetor + n) = malloc((n + 1) * sizeof(double)); 
} 

理由は、あなたがあなたのためにゼロバイトを割り当てるようにmalloc()を要求しているのでnは、最初の反復でゼロであること..です

ところで、ここで私がこのような種類の間違いをしないために通常使用しているのは、2d-dynamic-array-cです。

出力:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
5 
2.3 
1.4 8.2 
3.1 2.0 7.7 
5.3 6.1 4.4 1.2 
5.5 6.1 3.0 2.3 4.9 
-0.892202112506 
-1.307537578672 1.830552610141 
-0.523015031469 -1.030647267895 1.599810684493 
0.492249441383 0.861436522419 0.076913975216 -1.399834348932 
0.584546211642 0.861436522419 -0.569163416599 -0.892202112506 0.307655900864 

4.233333333333 2.166923061753 
C02QT2UBFVH6-lm:~ gsamaras$ 
+1

私は '3分で打ちなさい...':) ' –

+0

まだ何も答えずに作業しています。 –

+0

ああ、あなたの答えは答えでした。それは '(n + 1)'はすべての違いを作ります。残りの部分は、コアの問題を取り巻く別の改善点です。 –

3

あなたはすでにあなたの答えを受けているが、あなたは本当に検証する必要がある入力して配分を使用すると、任意の自信をあなたのコードを持ってしようとしている場合は、他のいくつかの領域があります実際の値で作業していて、ハードウェアのメモリの未知の部分に書き込みをしていません。常に、常に、ユーザー入力とメモリ割り当てを検証します。たとえば、コードを追加すると、次のようなコードを追加できます。例:

int ordem; 
if (scanf ("%d", &ordem) != 1) { 
    fprintf (stderr, "error: invalid input (ordem)\n"); 
    return 1; 
} 
double **vetor, 
     soma = 0; 
int elementos, n, m; 

elementos = (ordem * ordem + ordem)/2; 
if (!(vetor = malloc (ordem * sizeof *vetor))) { 
    fprintf (stderr, "error: virtual memory exhausted.\n"); 
    return 1; 
} 

for (n = 0; n < ordem; n++) 
    if (!(*(vetor + n) = malloc ((n + 1) * sizeof **vetor))) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

for (n = 0; n < ordem; n++) { 
    for (m = 0; m <= n; m++) { 
     if (scanf ("%lf", *(vetor + n) + m) != 1) { 
      fprintf (stderr, "error: invalid input (vetor + %d)\n", n); 
      return 1; 
     } 
     soma = soma + *(*(vetor + n) + m); 
    } 
} 

幸いです。

関連する問題