begin process at 2012 05 30 22:48:43
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C++ & C++ .NET

 > 

Windows

 > 

Autre

 > 

Violation d'accès lors de la lecture de l'emplacement 0x00000000.


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Violation d'accès lors de la lecture de l'emplacement 0x00000000.

dimanche 6 novembre 2011 à 12:16:21 | Violation d'accès lors de la lecture de l'emplacement 0x00000000.

d0jones

bonjour,
j'ai un petit souci, quand j'essai d'accéder à la donnée de ma struct j'ai le message suivant :
Exception non gérée à 0x01202029 dans ListTemplate.exe : 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000000.
Liste.h
Code C/C++ :
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#ifndef _LIST_
#define _LIST_

using namespace std;
template <typename T>
struct cell 
{	
public:
	T data;
	cell<T>* next;
};


template <class T>
class Liste
{
public:
	Liste(void)
	{
		this->first=NULL;
		this->last=NULL;
		this->size=0;
	}

	Liste(const Liste<T>& list)
	{
		if (list.size != 0 && list.first != NULL)
		{
			const  cell<T> *temp = list.first;
			while (temp->next != NULL)
			{
				this->AddInQueue(temp->data);
				temp = temp->next;
			}
		}
	}

	virtual ~Liste(void)
	{
		delete(this->first);
		delete(this->last);
	}

	int GetSize()
	{
		return this->size;
	}

	void AddInHead(T t)
	{
		cell<T>* c = new cell<T>();
		c->data = t;
		c->next = this->first;
		this->first = c;
		this->size++;
	}

	void AddInQueue(T t)
	{
		cell<T>* c = new cell<T>();
		c->data = t;
		c->next = NULL;
		this->last = c;
		this->size++;
	}

	void Concat(const Liste<T>& list)
	{
		if (list.first != NULL)
		{
			const  cell<T> *temp = list.first;
			while (temp->next != NULL)
			{
				this->AddInQueue(temp->data);
				temp = temp->next;
			}
		}
	}

	T ElementAt(int pos)
	{
		if (pos > this->size)
		{
			return NULL;
		}
		else 
		{
			const cell<T> *temp = this->first;
			int cpt = 0;
			for (int i=0; i<=pos; i++)
			{
				if (i == pos)
				{
					T data = temp->data;
					return data;
				}
				else
				{
					temp = temp->next;
				}
			}
			/*while (temp->next != NULL)
			{
				if (cpt == pos)
				{
					return temp->data;
				}
				cpt++;
				temp = temp->next;
			}*/
			return -1;
		}
	}

	inline const std::ostream & operator <<(std::ostream & out)
	{
		if (this->first != NULL)
		{
			const  cell *temp = this->first;
			for (int i = 0; i < this->size; i++)
			{
				out << (int)temp->data << " - " ; 
				temp = temp->next;
			} 
		}
		return out;
	}
	
private:
	int size;
	cell<T>* first;
	cell<T>* last;
};
#endif


le fichier Liste.cpp est vide

le main :

Code C/C++ :
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "liste.h"

using namespace std;


int main (int argc, char** argv)
{
	Liste<int>* list = new Liste<int>();
	cout << "constructeur par defaut : longueur de la liste : " << list->GetSize() <<endl;
	
	list->AddInHead(1);
	cout << "ajout en tete de '1' : longueur de la liste : " << list->GetSize() <<endl;
	cout << " contenu de la liste : " << list << endl;

	list->AddInQueue(2);
	cout << "ajout en queue de '2' : longueur de la liste : " << list->GetSize() <<endl;
	cout << " contenu de la liste : " << list << endl;

	cout << "element a la position 1 : " << list->ElementAt(1) << endl;

	Liste<int>* list1 = new Liste<int>();
	list1->AddInQueue(3);
	list1->AddInQueue(4);
	list1->AddInQueue(5);
	cout << "creation de la liste 1 contenant les elements '3,4,5'" <<endl;
	cout << " contenu de la liste : " << list1 << endl;

	list->Concat(*list1);
	cout << "concat de list(2) et list1(3) : longeur de la la liste : " << list->GetSize() << endl;
	cout << " contenu de la liste : " << list << endl;

	Liste<int>* list2 = new Liste<int>(*list);
	cout << "constructeur par recopie : longueur de la liste : " << list2->GetSize() << endl;
	cout << " contenu de la liste : " << list2 << endl;

	
	char n;
	scanf ("%c",&n);
	return 0;
}


pourquoi n'y ai je pas accès?
Merci d'avance
dimanche 6 novembre 2011 à 13:36:06 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

pop70

Salut, à mon avis il y a déjà un problème au niveau de cette ligne :

Code C/C++ :
 const  cell *temp = this->first; 


je mettrais plutôt:

Code C/C++ :
const  cell<T> *temp = this->first; 

sinon je ne pense pas que ça fonctionne.


idem pour

Code C/C++ :
      out << (int)temp->data << " - " ;


comme on ne sait pas quel type doit être affiché :

Code C/C++ :
       out << (T)temp->data << " - " ;


C++dialement,
Pop70
dimanche 6 novembre 2011 à 14:06:56 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

pop70

Et puis surtout :

Il faut indiquer la liste qui est affichée, et pour faire ça il faut rajouter un argument, et aussi que la fonction soit "friend" :

Code C/C++ :
    friend std::ostream& operator <<(std::ostream & out, Liste<T>& list)
    {
        if (list->ElementAt(0) != NULL)
        {
            const cell<T> *temp = list->ElementAt(0);
            for (int i = 0; i < list->GetSize(); i++)
            {
                out << (T)temp->data << " - " ;
                temp = temp->next;
            }
        }
        return out;
    }



Si ça ne fonctionne pas, tu peux essayer une fonction sans opérateur:


Code C/C++ :
   void aff ()
    {
        printf ("\naff:\n---\n");
        cell <T> *temp = first;
        for (int i=0; i < size; i++)
        {

            std::cout << (T)temp->data;
            temp = temp->next;
        }
        printf ("---\n");
    }

et faire list->aff().


Pop70
dimanche 6 novembre 2011 à 14:31:52 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

pop70

Réponse acceptée !
En fait j'en arrive à çeci :
Code C/C++ :
    friend std::ostream& operator <<(std::ostream& out, Liste<T>*& list) //(pour pouvoir faire std::cout << list)
    {
          if (list->ElementAt(0) != NULL)
        {
            const cell<T> *temp = list->GetFirst(); // ici il manque un <T>
            for (int i = 0; i < list->GetSize(); i++)
            {
                out << (T)temp->data << " - " ;
                temp = temp->next;
            }
        }

        return out;
    }


Mais il reste une erreur dans AddInQueue: last pointe sur la dernière cellule, lui affecte sa valeur, et indique que la suivante ne pointera sur rien. Mais à quelle moment la variable next de l'avant-dernière cellule pointe sur la nouvelle
Jamais, donc la liste contient bien le nombre d'éléments voulu, mais ils ne sont pas reliés entre eux... Contrairement à la fonction AddInHead, qui elle fonctionne correctement, et du coup fait planter l'affichage.


C++dialement,

Pop70
dimanche 6 novembre 2011 à 23:08:17 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

d0jones

Merci pour tes réponses, il n'y a plus de violation d'accès, de plus tu as levé un bug avec AddInQueue.
Encore merci, et bonne fin de week end.
dimanche 6 novembre 2011 à 23:17:04 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

d0jones

De même quand j'ajoute le premier element, il faut que first et last pointe sur celui ci.
Il y a en core deux ou trois petites failles.
Merci
lundi 7 novembre 2011 à 11:16:46 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

CptPingu

Administrateur CodeS-SourceS
pop70 a répondu à ta question mais j'aimerais soulever quelques maladresse de code:

#pragma once


Ce n'est pas standard et n'a rien à faire ton code (c'est un pseudo-remplaçant de la guarde que tu as de toute façon écrite).

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#ifndef _LIST_
#define _LIST_


Les "includes" devraient être à l'intérieur de la garde et pas au dessus. (Donc les "includes" en dessous du ifndef/define)

using namespace std;


Évite les "using namespace", voir: [ Lien ]

struct cell


En C++, une structure et une classe, c'est la même chose. Donc "cell" devrait avoir une majuscule, et le "public" est inutile, puisqu'une struct est déjà publique par défaut.
De même, généralement un nom de méthode commence par une lettre minuscule.

Liste(void)


Devrait être List(). En C++, une fonction qui ne prend pas d'argument s'écrit comme cela. Il n'y a qu'en C où l'on est obligé de mettre "void".

int size;
cell<T>* first;
cell<T>* last;


On met généralement un différenciateur sur les attributs de classe. Par exemple "first" devrait être "_first".

this->size=0;


Les "this->" sont inutiles, et il est d'usage de ne pas les mettre.


this->first=NULL;
this->last=NULL;


Évite les NULL, voir: 0217021.free.fr/portfolio/axel.berardino/articles/null-en-cpp. Préfère 0 (ou "nullptr" si tu es en C++0x).

Liste(void)
{
this->first=NULL;
this->last=NULL;
this->size=0;
}


Utilise la liste d'initialisation dès que tu le peux ! Devrait être:
Code C/C++ :
Liste()
: _first(0), _last(0), _size(0)
{
}


delete(this->first);


Pas besoin de parenthèse, "delete" est un mot clé et non une fonction. => delete _first;

virtual ~Liste(void)


Le virtual est inutile ici. Tu peux le retirer. => ~Liste()

if (pos > this->size)
{
return NULL;
}
else
{
// code
}


Le "return" est débranchant. Donc il est inutile de mettre un "else". Pas besoin non plus de crochets lorsque tu as une seule instruction.
Code C/C++ :
		if (pos > this->size)
			return NULL;
                // code

(À corriger partout)

Enfin pour la fonction d'affichage, il est d'usage de ne pas utiliser de friend (ni de cast d'ailleurs). On réalise généralement une fonction publique "print" qui prend un std::ostream en argument. Puis on appelle cette fonction dans la fonction de "sucrement".
Ça permet de laisser la logique au sein de la classe, et de laisser le rôle de sucrement à la fonction de sucrement.

Ex:
Dans ta classe:
Code C/C++ :
    void print(std::ostream& out)
    {
        if (list->ElementAt(0) != 0)
        {
            const cell<T> *temp = list->GetFirst();
            for (int i = 0; i < list->GetSize(); ++i)
            {
                out << temp->data << " - " ;
                temp = temp->next;
            }
        }
    }

En dehors:
Code C/C++ :
    std::ostream& operator <<(std::ostream& out, const Liste<T>& list)
    {
        list.print(out);
        return out;
    }

Ce qui au passage, ne nécessite pas de friend.

Au niveau de ton main:
Pas besoin de faire des new (surtout que tu oublies les delete qui vont avec !).
Tu peux directement remplacer: "Liste<int>* list = new Liste<int>();" par "Liste<int> list;" (et donc toutes les "->" deviennent des ".").
Les includes du C n'ont rien à faire là (donc retire les stdio.h et stdlib.h). Si tu veux mettre une pause, un "std::cin.get()" remplacera avantageusement ton scanf.

Enfin, sépare la déclaration et le code. Il ne devrait pas y avoir de code dans un header.

________________________________________________________________________
Historique de mes créations, et quelques articles:
http://0217021.free.fr/portfolio
Merci d'utiliser Réponse acceptée si un post répond à votre question
lundi 7 novembre 2011 à 12:33:51 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

pop70

Y'a quelques points sur lesquels je suis pas tout à fait d'accord :

En dehors:

Code C/C++ :

std::ostream& operator <<(std::ostream& out, const Liste<T>& list)
{
list.print(out);
return out;
}

Ce qui au passage, ne nécessite pas de friend.




Sans friend, l'operateur de flux << n'est pas valide, le compilo retournera

...\main.cpp|147|error: 'std::ostream& Liste<T>::operator<<(std::ostream&, Liste<T>*&)' must take exactly one argument



à la différence des opérateurs + - = ...

Sinon pour l'abscence de void je ne suis pas sûr, en C le type de retour par défaut est bien int, mais en C++ ça semble l'être aussi : en l'abscence de type de retour et de retour on obtient un warning :

warning: no return statement in function returning non-void



qui n'est résolu qu'en retournant un entier.

De plus même en retournant un entier, certains compilos (comme Code::Blocks), disent avoir une erreur ISO C++ qui interdit la déclaration sans type :

...\main.cpp|76|error: ISO C++ forbids declaration of 'AddInQueue' with no type|




Sinon pour le reste je suis totalement d'accord

C++dialement,
Pop70
lundi 7 novembre 2011 à 13:29:47 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

CptPingu

Administrateur CodeS-SourceS

Sans friend, l'operateur de flux << n'est pas valide, le compilo retournera


Attention, ne pas confondre (la version interne):
std::ostream& Liste<T>::operator<<(std::ostream&)
et (la version externe):
std::ostream& operator<<(std::ostream&, const Liste<T>&)
qui sont deux surcharges différentes (qui ont à peu près le même effet, je ne rentre pas dans les détails).

Voici un exemple très simple qui étayera mes dires:
Code C/C++ :
#include <iostream>

class Test
{
public:
  Test()
    : _a(1), _b(2), _c(3)
  {
  }

  void print(std::ostream& out) const
  {
    out << _a << " " << _b << " " << _c;
  }
private:
  int _a;
  int _b;
  int _c;
};

std::ostream& operator<<(std::ostream& out, const Test& test)
{
  test.print(out);
  return out;
}

int main()
{
  Test test;

  std::cout << test << std::endl;

  return 0;
}



Sinon pour l'abscence de void je ne suis pas sûr, en C le type de retour par défaut est bien int,


Je parle du void en argument, et non du type de retour. Ex: int func(void) en C++ s'écrit int func().
En C, int func() veut dire "nombre d'argument inconnu" et int func(void) veut dire "pas d'argument".
En C++, la notion de "nombre d'argument inconnu" est retirée, et on a adopté l'écriture "int func()".

Je te remercie des remarques, car tu viens de me faire remarquer que je n'ai peut être pas été clair dans mes explications :)

________________________________________________________________________
Historique de mes créations, et quelques articles:
http://0217021.free.fr/portfolio
Merci d'utiliser Réponse acceptée si un post répond à votre question
lundi 7 novembre 2011 à 16:52:40 | Re : Violation d'accès lors de la lecture de l'emplacement 0x00000000.

pop70

Ah d'accord !
Merci pour les précisions

Sinon j'avais jamais fait la différence entre int funct(void) et int funct() en C ; en fait une fois j'avais essayé les 2 puis fait un objdump, mais le code assembleur était identique (du moins au point de vue du main), donc j'en avais conclu que c'était pareil. Mais du coup j'imagine que int func(void) respecte plus les normes :)



Pop70


Cette discussion est classée dans : liste, first, temp, list, cell


Répondre à ce message

Sujets en rapport avec ce message

erreur dans la fonction d'impression [ par dark_cross ] voici j'ai une erreur dans ma fonction d'impression si quelqu'un peux m'expliquer, je serais tres ravie.#include #include //speciale dedicasse Etienne List de l'aide svp [ par silverfr78021959 ] Bonjour voilà je dois créer une liste et de la en faire l'affichage, mais cette affichage doit être fait particulierement. Je m'explique je voudrais a fuite memoire dans un programme [ par donlefou ] bonjour, quelqu'un pourrait regarder mon code pour voir d'où vient mes fuites memoires :template void C_Liste::ajouter_element(T elt){ // On crée un c list<> & API [ par Taron31 ] Bonjour, je suis confronté à un problème relativement étrange depuis hier et je ne parviens pas à le résoudre. En effet, je fais un programme avec API Fusion de cellules pour une liste chainée [ par ouhare ] Bonjour tout le monde. J'aurais une question concernant une fonction en C que j'appelerais merge_list(). Cette fonction est supposée fusionner 2 cellu initialiser une liste : fonction récursive ? [ par netwebzone ] Bonjour Je dois créer une fonction qui initialise une liste chaînée à partir d'un nombre d'élement passé en paramètre pour la taille de la liste. J'ai Liste stl et fonction constante [ par poiuytrez3 ] Bonjour,J'ai une erreur de compilation lorsque je veux définir un cursor au début de ma liste qui est dans mon objet.La fonction est constante et le c liberer un emplaceemnt dans une "list" en c++ sans supprimer l'objet [ par timy94 ] BonjourVoici mon codeCEvenement & MyClasse::Get_Evt(){       list ::iterator pEvt;       list ::iterator pListEvt = m_Liste_Evt.begin();        pEvt Problème de chainage dans un tableau dynamique [ par hachure1 ] Voila ce bout de code qui extrait les données d'un graphe dans un fichier et stoke cela dans un tableau dynamique contenant de sommets ou chaque case


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,905 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales