2010-12-11 1 views
2
#include <stdio.h> 
#include <iostream> 
#include <stdlib.h> 
#include <string.h> 

using namespace std; 

void multiplier_matrice_vecteur (char * v0, char * A, int N) 
{ 
    int i,j,k; 
    char somme; 

    for (i = 0; i < N; i++) //On fait N calculs car c'est une matrice 1xN 
    { 
     //On fait N additions + multiplications 
     somme = 0; 
     for (j = 0; j < N; j++) 
     { 
      somme += v0[i] * A[i * N + j]; 
     } 
     v0[i] = somme; 
    } 
} 

int main(void) 
{ 
    bool premiereLignefaite = false; 
    //Lire le fichier 
    FILE * graphe = fopen("graphe.txt", "r"); 
    //Fichier de sortie 
    FILE * resultat = fopen("resultat.txt", "w"); 
    int nbr1, nbr2; 
    int N; 
    char *matrice; //pointeur vers la matrice d'adjacence 

    //Ligne lue 
    static char ligne[50]; 

    while (fgets(ligne, 50, graphe) != NULL) //retourne 0 quand on a end-of-file 
    { 
     //La premiere ligne est différente 
     if (premiereLignefaite == false) { 
      //Initialiser une matrice d'adjacence NxN 
      sscanf(ligne, "%d %d", &nbr1, &nbr2); 
      N = nbr1; 
      matrice = new char(nbr1 * nbr1); //Memoire dynamique pour la matrice dadjacence n x n 
      memset(matrice, 0, nbr1*nbr1); 
      premiereLignefaite = true; 
      continue; 
     } 
     //On construit notre matrice d'adjacence 
     sscanf(ligne, "%d %d", &nbr1, &nbr2); 
     matrice[nbr1 * N + nbr2 ] = 1; 
    } 

    printf("Matrice d'adjacence %dx%d : \n", N, N); 
    //Affichage de la matrice d'adjacence 
    for (int i = 0; i < N; i++) 
    { 
     for (int j = 0; j < N; j++) 
     { 
      printf("%c ", matrice[i * N + j] + '0'); 
     } 
     printf("\n"); 
    } 

    //Application de l'algo étapes par étapes 
    double tolerance = 0.00001; //Niveau de tolérance de la méthode 
    char * v0; //vecteur propre taille N 
    char * v; //vecteur tampon 
    int valeur; //valeur propre 
    int valeur_tamp; //valeur propre tampon 

    //Initialiser v0 
    v0 = new char(N); 
    memset(v0, 1, N); 

    //Initialiser A (déja fait) 
    //Initialiser tolérance (deja fait) 

    valeur = 0; 
    while (1) 
    { 

     valeur_tamp = valeur; 
     //Multiplication du vecteur par la matrice 
     multiplier_matrice_vecteur(v0, matrice, N); 
    } 

    //Désallocation de la mémoire 
    delete matrice; 

    //Fermeture des fichiers etc 
    fclose(graphe); 
    fclose(resultat); 

    return 0; 
} 

これは私のラップトップで2PM以来コーディングしているプログラムです。私はVisual Studio 2008とWindows 7の64ビットを使用しています。私はコーディングしている、すべてうまくいっている。プログラムをテストしようとすると、次の行が表示されます。newとmallocによってNULLポインタが返されたのはなぜですか?

v0 = new char(N); 

私には例外があります。私はmallocとcallocで私の記憶を得ようとしています。何が得られますか?ヌルポインタ!!私は私のマシンに4ギガのラムを持っています。私はここで9バイトのメモリを得ることができません。私はこれを全く理解していません。 Visual Studio 2008を持ち、同じエンバイロメントの下でテストしたい人のために

、ファイルgraphe.txtが必要になり、ここでそのファイルがあります:

9 20 
0 1 
0 2 
1 0 
1 2 
1 3 
1 5 
2 0 
2 1 
2 3 
3 1 
3 2 
3 4 
4 3 
5 1 
5 6 
5 7 
6 5 
6 8 
7 5 
8 6 

私は、これは機械の問題だと思いました私は家に帰って、私はデスクトップコンピュータでプログラムを試してみると同じ問題です...

私はGCCを試してみたいと思いますが、私はいつもVisual C++を使っていますので、この問題を解決したい環境...

EDIT:以下のコードが機能するようになりました。何らかの理由で、最初の新規でカッコを使用するとうまくいきますが、次回新しいときには機能しません! []構文を使用して両方の新しい割り当てを行うと、それは機能します。私が最初の新しい割り当てを[]で置き、2番目の割り当てを()で行うと、それも機能します。 WEIRD。とにかく、今から[]を使用しています...ありがとうございました。

+0

制御が例外を伴ってその行に達したときに「N」と表示される場合の値は? – Kos

+1

例外がここにないのですか? 'memset(v0、1、N);' – Cam

+0

いいえ、ここでmemsetを実行しようとする前に起こります。 – toto

答えて

4

あなたは

matrice = new char[nbr1 * nbr1]; 

を使用して、私はあなたのコードをテストすることはできません

delete[] matrice; 
+3

C++、BTWでは動的配列に対して 'boost :: array'または' std :: vector'を使用しています。 – Kos

+0

あなたは().Okの代わりに[]を使うことを提案していますが、それは同じことをします。 – toto

+5

@toto:Erm、いいえ? 'new char(n)'は初期化されていない文字を 'n 'に割り当てますが、' new char(n) 'は値' n'に初期化された一つの文字を割り当てます。 – fredoverflow

2

を解放することを忘れないでください、しかし、あなたはきれいではない何かを行う必要があります。

あなたは int N;変数あなたは、少なくともよりmayberはるかに大きく、これまでにあなたのループはNはあなたが望むように初期化されていないことを行った場合、その後、あなたのNはランダムな整数であるint N =0;

を書くべきで初期化されません。 newで使用すると利用可能なメモリです。

ちょっと私の小さな仮定。

編集:私は私はあなた「graphe.txt」のeampleを持っていない、あなたのコードの原因をテストすることはできません...ので、私は、当面の問題は丸い括弧の使用ではなく、ファイル

+1

これも私が考えていたものです。 +1。また、このようなものを追加したいのですが、警告をすべて有効にすれば、より簡単に回避できます。 – Cam

+0

私はv0 = new char(4)でテストしました。これは、問題ではありません! – toto

+0

@Camは、我々がすべてのこの問題ではない[OK]を初期化されていない整数;-) –

3

から何も読みません角括弧。

しかし、生の配列の代わりにstd :: vectorを使用します。あなたの割り当てと割り当て解除を行います。正しく

歓声& HTH、

+0

いいえ、括弧は1文字を割り当てるときに有効です。それはコンストラクタに値を渡すための構文です。 –

+0

+1のstd :: vectorの助言のために、これはC++です。 –

+0

@Jonathan:wtf。あなたは「いいえ」という意味ですか?あなたのコメントの残りの部分は、文字通り真実ですが、あなたはコードが* *について何でも確認しましたか? –

4

あなたのコードが悪いバグがあります。

//Initialiser v0 
v0 = new char(N); 
memset(v0, 1, N); 

おそらくNの文字を割り当てるために、 "新しいのchar [N]" を意味します。しかし、あなたのコードは値1で1バイトしか割り当てません。次に、V0からVO + n-1までのメモリを上書きします。ここで上書きしているメモリは誰が知っていますか。

+0

+1素晴らしいショット、私はこれを見ることができませんでした、私は私のCを失っています...多分私たちはC配列の代わりにstd :: vectorを使用するよう助言しなければなりません... –

0

v0 = new char(N)は、値Nの1文字を割り当てます。配列を割り当てることを意味しましたか?

それを超えると、あなたの質問はちょっと混乱します。 nullを返すか、例外を送出しますか?同じ行は両方をしません。

0

私はsje397が指摘したようにあなたは、単一の文字ではなく、配列を割り当てたので、あなたは、少なくとも小さなコーディング1を確認するために、いくつかのミス

  1. をしたと思います。私はあなたがその違いを知っていて、それが単にタイプミスであったことを願っています。

  2. C++を最初に読んでいなくてもかなり深刻なことです(C++がそのように使用することは誰も知りません)。std :: vectorの仕事です。 C++は単なる実験ではまともに学ぶことができない言語ではありません。悲しいことですが、それは事実です... C++では、間違いを犯すと恐ろしい未定義のモンスターが得られます。これは簡単な方法ではありません。歴史的な事故(遺産、青少年の誤り、委員会の影響)のために、この言語は複雑で非論理的で、多くの分野でこのように扱われています。歴史を推測する:歴史を学ばなければならない。あなたがC++を学ぶことに興味があるなら、あなた自身に好意を持ち、よいC++の本を選んで最初に少し読んで始めてください... C++は非常に素晴らしく強力な武器ですが、それを間違った側から攻撃してみてください。

  3. 非常に深刻な姿勢です。プログラムに問題があるときは、問題の99.999%があなたのコードにあります。これはコンパイラのバグではありません。これはOSのバグではありません。それは欠陥のあるRAMではありません。あなたのコードだけが間違っているので、問題を検索して修正する必要があります。他の人のコードに問題があることを最初に考える習慣を保つことは、プログラミングにおいてあなたを遠くに導かないでしょう。

+0

ねえ、あなたは正しいですが、ここで少し失礼です。私がベクトルの代わりに純粋な配列で作業したいのであれば、それは私の選択です。ベクトルはライブラリにあり、charは言語にあるので、私はC++をやっています。私はポイントナンバー3に同意します。 – toto

+0

それは失礼に聞こえるが、それは私の個人的な経験から来るアドバイスですが、ごめんなさい。私は実際に言語を勉強する時間を取る前に、多くのC++プログラムを書いていました。 std :: vectorの代わりにmalloc(1 + strlen(...))/ strcpyを使いたいと思うような選択肢があります。これが間違いではないケースはごくわずかです。非常に多くの点であなたのコードは本当にあなたがC++のテキストを読む時間を費やさなかったと叫びます。本当に違いを生むことができると信じてください。試してみる。 – 6502

関連する問題