2010-12-11 5 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; 
} 

Donc, c'est le programme que j'ai codé depuis 2PM sur mon ordinateur portable. J'utilise Visual Studio 2008 et Windows 7 64 bits. Je code, tout va bien. Lorsque j'essaie de tester mon programme, la ligne:Pointeur NULL renvoyé par new et malloc, pourquoi?

v0 = new char(N); 

Me donne une exception. J'essaie de retrouver ma mémoire avec malloc et calloc et qu'est-ce que je reçois? Un pointeur nul !! J'ai 4 concerts de ram sur ma machine et il n'y a aucun moyen que je ne peux pas obtenir 9 octets de mémoire ici. Je ne comprends pas ça du tout.

Pour ceux qui ont Visual Studio 2008 et que vous souhaitez tester dans le même environnement, vous aurez besoin du fichier graphe.txt, voici ce fichier:

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 

Je pensais que cela était un problème de machine, Je rentre à la maison, j'essaye le programme sur mon ordinateur de bureau et c'est le même problème ...

Je devrais essayer sur GCC mais puisque j'utilise toujours Visual C++ je veux résoudre le problème sur ceci environnement ...

EDIT: Le code suivant fonctionne maintenant. Pour une raison quelconque, si vous utilisez des parenthèses dans la première nouvelle, cela fonctionnera, mais la prochaine fois que vous utiliserez de nouvelles, cela ne fonctionnera pas !! Si je mets les deux nouvelles allocations avec la syntaxe [], cela fonctionne. Si je mets la première nouvelle allocation avec [] et la seconde avec(), cela fonctionne aussi. BIZARRE. De toute façon, je vais utiliser [] à partir de maintenant ... Merci à tous.

+0

Quelle est la valeur si 'N 'lorsque le contrôle atteint cette ligne avec l'exception? – Kos

+1

Etes-vous sûr que l'exception n'est pas ici? 'memset (v0, 1, N);' – Cam

+0

Non, cela arrive avant d'essayer de faire le memset ici. – toto

Répondre

4

Vous devez utiliser

matrice = new char[nbr1 * nbr1]; 

et souvenez-vous de libérer avec

delete[] matrice; 
+3

Nous avons 'boost :: array' ou' std :: vector' pour les tableaux dynamiques en C++, BTW. – Kos

+0

Vous suggérez que j'utilise [] au lieu de(). Ok mais ça fait la même chose. – toto

+5

@toto: Euh, non? 'new char [n]' alloue 'n' des caractères non initialisés, alors que' new char (n) 'alloue un seul caractère initialisé à la valeur' n'. – fredoverflow

2

Je ne peux pas tester votre code, mais vous faire quelque chose pas propre.

Vous ne vous devriez au moins pas vous initialisez la variable int N; écrire int N =0;

si jamais votre boucle fait que N est pas initialisé la façon dont vous voulez, votre N est un nombre entier aléatoire, beaucoup plus grande que mayber la mémoire disponible lorsque vous l'utilisez avec new.

Juste ma petite supposition.

EDIT: je ne peux pas tester votre code parce que je n'ai pas eample vous « graphe.txt » ... donc je ne lis rien de fichier

+1

C'est ce que je pensais aussi; +1 Aussi, j'aimerais ajouter que des choses comme celles-ci peuvent être évitées plus facilement si vous activez les avertissements tout le long. – Cam

+0

J'ai testé avec v0 = new char (4); ce n'est pas le problème !!! – toto

+0

@Cam il semble que nous avons tous erré entre les cauchemars des entiers non initialisés ;-) –

3

le problème immédiat est votre utilisation de parenthèses ronde au lieu de crochets.

mais utilisez std :: vector au lieu des tableaux raw. il fait l'allocation et la désaffectation pour vous. correctement. .

acclamations & HTH,

+0

Non, les parenthèses sont valides lors de l'allocation d'un seul caractère. C'est la syntaxe pour passer une valeur au constructeur. –

+0

+1 pour le conseil de std :: vector, ceci est C++. –

+0

@Jonathan: wtf. voulez-vous dire par "non"? et le reste de votre commentaire, oui littéralement vrai, mais avez-vous vérifié tout ce que le code est * sur *? –

4

Votre code a un mauvais bug:

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

Vous voulez dire probablement "new char [N]" d'allouer N caractères. Mais votre code alloue seulement 1 octet avec la valeur N.Ensuite, vous remplacez la mémoire de V0 à VO + n-1 à 1. Qui sait quelle mémoire vous écrasez ici.

+0

+1 belle prise de vue, je ne pouvais pas voir ça, je perds mon C ... peut-être que nous devrions lui conseiller d'utiliser std :: vector au lieu de C arrays ... –

0

v0 = Le nouveau caractère (N) alloue un seul caractère avec la valeur N. Vouliez-vous attribuer un tableau? Au-delà de cela, votre question est un peu déroutante. Est-ce qu'il renvoie null ou déclenche une exception. La même ligne ne fera pas les deux.

0

Je pense que vous avez fait plusieurs erreurs

  1. Pour assurer au moins un petit codage parce que l'un sje397 a fait remarquer que vous allouez un seul omble chevalier et non un tableau. J'espère que vous connaissez la différence et que ce n'était qu'une faute de frappe.

  2. Une utilisation plus sérieuse de l'utilisation de C++ sans avoir rien lu à ce sujet (personne ne connaissant C++ utiliserait new de cette façon ... c'est un travail pour std :: vector). C++ n'est pas un langage que vous pouvez espérer apprendre à un degré décent par simple expérimentation. C'est triste mais c'est un fait ... en C++ quand vous faites des erreurs vous obtenez le redoutable monstre Undefined Behaviour et ce n'est pas un moyen facile d'apprendre; ceci est particulièrement vrai pour le C++ car la langue est à la fois complexe et illogique dans de nombreux domaines et cela en raison d'accidents historiques (héritage, erreurs de jeunesse, effet de comité) ... peu importe votre intelligence, vous ne pouvez pas devinez l'histoire: l'histoire doit être étudiée. Si vous êtes intéressé par l'apprentissage C++ alors s'il vous plaît faites-vous plaisir et choisissez un bon livre C++ et commencez par lire un peu ... C++ est une arme très belle et puissante à posséder, mais elle peut facilement devenir votre pire cauchemar. essayez de l'attaquer du mauvais côté.

  3. Un très sérieux avec l'attitude. Quand un programme a un problème, alors 99,999% des fois le problème est dans votre code. Ce n'est pas un bug dans le compilateur. Ce n'est pas un bug dans OS. Ce n'est pas une RAM défectueuse. C'est juste votre code qui est faux, donc vous devez rechercher et résoudre le problème. Garder l'habitude de penser d'abord que le problème est dans le code de quelqu'un d'autre ne vous mènera pas vraiment loin dans la programmation.

+0

Hey, vous avez raison, mais je pense que vous êtes un peu grossier ici. Si j'aime travailler avec des tableaux purs au lieu de vecteurs, c'est mon choix. le vecteur est dans la bibliothèque, char est dans la langue, donc je suis en train de faire du C++. Je suis d'accord avec le point numéro 3. – toto

+0

Je suis désolé si cela a paru impoli mais c'est un conseil venant de mon expérience personnelle. J'ai écrit beaucoup de programmes en C++ avant de prendre le temps d'étudier réellement la langue et croyez-moi, ça fait une énorme différence. Si vous voulez utiliser la mémoire brute de cette façon même en connaissant std :: vector, alors c'est un choix comme si vous vouliez aller avec malloc (1 + strlen (...))/strcpy au lieu de std :: string mais il y a très peu de cas dans lesquels ce ne serait pas une erreur. Votre code dans beaucoup de points crie vraiment que vous n'avez jamais pris le temps de lire n'importe quel texte C++. Croyez-moi, cela peut vraiment faire la différence. Essaie. – 6502

Questions connexes