IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Violation d'accès lors de la lecture


Sujet :

Langage C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2013
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Violation d'accès lors de la lecture
    Bonjour,

    après quelques années sans coder, je revoilà dans le domaine et j'ai les neurones qui s'échauffent.
    Je dois coder pour le boulot un petit bout de code qui génère une table semi aléatoire de dimension X*Y et pour cela j'alloue de la mémoire, je passe tout ce qui va bien en paramètre d'une fonction (un pointeur sur la table et les paramètres X et Y). La dite fonction génère aléa et le stocke dans le tableau passé en argument.

    Ensuite dans ma boucle main, je réitère sur mon tableau pour afficher les valeurs générées et la boum !! Erreur de violation d'accès en lecture.
    J'ai épuré mon code au max pour ramener au strict minium pour voir d'où vient le PB, je trace au débuggeur et ça semble marcher, mais nada, ca plante systématiquement sur le "cout" d'affichage.

    Je suis certain d'avoir écrit un mauvais code et de faire une confusion au niveau du pointeur sur le tableau, mais je trouve pas la solution.

    Je sèche sur le sujet. si vous avez une idée. Pour info je code sous Visual Studio Community 2017.

    Voici mon code qui bugge.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
     
    #include <iostream>
     
    using namespace std;
     
    void initPerlinNoiseTable(float *tableToFill, int height, int width)
    {
    	int random;
    	float random11;
    	for (int j = 0; j < height; j++)
    	{
    		for (int i = 0; i < width; i++)
    		{
    			random = rand();
    			random11 = (float)(float(random) / float(RAND_MAX));
    			random11 = (float)(2.0f*(float(random11) - 0.5f));
     
    			//cout << float(random11) << " ";
    			int shiftmemory = (j*width + i) * sizeof(float);
    			*( tableToFill + shiftmemory ) = random11;
    		}
    		cout << endl;
    	}
    }
     
     
    int main() {
     
    	float *arrayPerlinNoise=NULL;
     
    	int arrayHeight = 2;
    	int arrayWidth = 2;
     
    	arrayPerlinNoise = (float*) malloc(arrayHeight*arrayWidth*sizeof(float));
     
    	initPerlinNoiseTable(arrayPerlinNoise, arrayHeight, arrayWidth);
     
    	for (int j = 0; j < arrayHeight; j++)
    	{
    		for (int i = 0; i < arrayWidth; i++)
    		{
    			int shiftmemory = (j*arrayWidth + i) * sizeof(float);
     
    			float value = *(arrayPerlinNoise+ shiftmemory);
    			cout << value << " ";
    		}
    		cout << endl;
    	}
     
    	free(arrayPerlinNoise);
     
    	system("pause");
     
    	return 0;
    }

    Merci bcp,

    Sly

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int shiftmemory = (j*width + i) * sizeof(float);
    			*( tableToFill + shiftmemory ) = random11;
    Ton tableToFill est un float* donc les décallages se font déjà de float en float. En multipliant en plus par sizeof(float) tu débordes très clairement.

    Sinon, quitte à vouloir écrire du C++ : std::vector, std::array
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2013
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci Bousk,

    J'ai modifié en conséquence comme cela (qui fonctionne).
    Je retiens que le std::vector et array sont plus adaptés, mais c'était pour comprendre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    #include <iostream>
     
    using namespace std;
     
    void initPerlinNoiseTable(float *tableToFill, int height, int width)
    {
    	float *pointer;
     
    	pointer = tableToFill;
     
    	int random;
    	float random11;
    	for (int j = 0; j < height; j++)
    	{
    		for (int i = 0; i < width; i++)
    		{
    			random = rand();
    			random11 = (float)(float(random) / float(RAND_MAX));
    			random11 = (float)(2.0f*(float(random11) - 0.5f));
     
    			*pointer = random11;
    			pointer++;
    		}
    		cout << endl;
    	}
    }
     
     
    int main()
    {
     
    	float *arrayPerlinNoise = NULL;
     
    	float * pointer;
     
    	int arrayHeight = 5;
    	int arrayWidth = 5;
     
    	arrayPerlinNoise = (float*)malloc(arrayHeight*arrayWidth * sizeof(float));
    	pointer = arrayPerlinNoise;
     
    	initPerlinNoiseTable(arrayPerlinNoise, arrayHeight, arrayWidth);
     
    	for (int j = 0; j < arrayHeight; j++)
    	{
    		for (int i = 0; i < arrayWidth; i++)
    		{
    			float value = *pointer;
    			cout << value << " ";
    			pointer++;
    		}
    		cout << endl;
    	}
     
    	free(arrayPerlinNoise);
     
    	system("pause");
     
    	return 0;
    }
    je conviens parfaitement que ce n'est pas le code le plus élégant au monde, mais ca permet de manipuler la mémoire et de comprendre comment cela fonctionne.

    Merci.

    Sly

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Sans aller jusqu'à utiliser algorithm (generate, back_inserter, ...), vector et array sont le niveau 0 du C++.
    Manipuler la mémoire pour manipuler la mémoire est au mieux inutile.
    Ton code est du C qui utilise std::cout.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je plussoie. Ton code sera bien plus simple, maintenable, et correct avec un vector...

    Un truc genre (code non testé):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    vector<float> perlinNoise;
    for(int i = 0; i< arrayHeight * arrayWidth ; ++i)
      perlinNoise.push_back(randomValue());
    De plus, pour l'aléatoire, selon ce que tu veux en faire, rand n'est pas forcément très bien. Il présente beaucoup de biais, et n'est pas de bonne qualité. Il vaut mieux utiliser ce qui est dans <random> (même si c'est un peu plus complexe au premier abord...)
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2013
    Messages : 3
    Points : 3
    Points
    3
    Par défaut

    De plus, pour l'aléatoire, selon ce que tu veux en faire, rand n'est pas forcément très bien. Il présente beaucoup de biais, et n'est pas de bonne qualité. Il vaut mieux utiliser ce qui est dans <random> (même si c'est un peu plus complexe au premier abord...)

    Effectivement le <Random> n'est pas un générateur aléatoire, mais dans mon cas il fait exactement ce dont j'ai besoin car il me renvoie une suite pseudo-aléatoire (suffisamment aléatoire pour mes besoins en tout cas) et surtout offre l'avantage de systématiquement renvoyer la même suite quelle que soit le moment où je j'appelle ma fonction. Il s'agit de cette spécificité dont j'ai besoin pour mon application.

    Slts

    Sly

  7. #7
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    En C++, ça donnerait plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include <iostream>
    #include <vector>
    #include <random>
    #include <algorithm>
     
    class NoiseTable {
    public:
    	NoiseTable( size_t height, size_t width ) : width(width), table(height*width) {
    		std::mt19937  gen{};        // => on aura toujours la même séquence
    		std::uniform_real_distribution<float>  dis( -0.5f, +0.5f );
     
    		std::generate( std::begin(table), std::end(table), [&]{ return dis(gen); } );
    	}
    	float *operator[]( size_t line ) {
    		return table.data() + width * line;
    	}
    	const float *operator[]( size_t line ) const {
    		return table.data() + width * line;
    	}
    private:
    	size_t  width;
    	std::vector<float>  table;
    };
     
     
    int main() {
    	const size_t  arrayHeight = 5;
    	const size_t  arrayWidth = 5;
     
    	NoiseTable  arrayPerlinNoise( arrayHeight, arrayWidth );
     
    	for ( size_t j = 0 ; j < arrayHeight ; ++j ) {
    		for ( size_t i = 0 ; i < arrayWidth ; ++i ) {
    			std::cout << arrayPerlinNoise[j][i] << " ";
    		}
    		std::cout << std::endl;
    	}
    }
    Est-ce plus compliqué? C'est en tout cas plus du C++.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par slyvtt Voir le message
    systématiquement renvoyer la même suite quelle que soit le moment où je j'appelle ma fonction. Il s'agit de cette spécificité dont j'ai besoin pour mon application.
    Pour ça il faut juste utiliser la même seed pour initialiser le générateur.
    En l'état, ton random pourrait ne pas retourner les mêmes résultats sur différentes machines. Ou selon tout critère masqué et incontrôlé qui initialise la seed.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Violation d'accès lors de la lecture
    Par moooona dans le forum MFC
    Réponses: 2
    Dernier message: 27/05/2010, 17h52
  2. Réponses: 5
    Dernier message: 01/12/2009, 01h06
  3. Réponses: 7
    Dernier message: 13/08/2009, 09h01
  4. Réponses: 5
    Dernier message: 02/01/2009, 10h37
  5. Violation d'accès lors de la lecture
    Par Fullmetal82 dans le forum C++
    Réponses: 9
    Dernier message: 29/11/2007, 17h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo