Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Débuter
Débuter Forum d'entraide pour débuter en langage de programmation C++. Avant de poster : cours d'initiation au C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 20/11/2012, 12h59   #1
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Par défaut Retour new sur pointeur alloué à nul

Bonjour à tous,

suite à des recherches sur cette question, je ne trouve pas de réponse pertinente. Voici déjà le code d'exemple:
Code :
1
2
3
4
5
 
...
ClasseA * ptA( 0 );
ptA = new ClasseA();
...
dans le cas où il y ait une mauvaise allocation avec l'opérateur "new", problème d'espace mémoire étant je pense le plus courant,"ptA" vaudra-t-il toujours 0 ?

Merci beaucoup pour vos réponses.
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 13h09   #2
Neckara
Rédacteur
 
Avatar de Neckara
 
Homme Denis
Étudiant
Inscription : décembre 2011
Messages : 2 538
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Loire (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : décembre 2011
Messages : 2 538
Points : 6 806
Points : 6 806
Envoyer un message via MSN à Neckara Envoyer un message via Skype™ à Neckara
Bonjour,

A ce que je sache, new lancera une exception en cas d'erreur lors de l'allocation mémoire.
Il existe toute fois un moyen pour forcer new à renvoyer NULL en cas d'erreur :
Code :
Type *ptr = new(std::nothrow) Type;
__________________
Recherche devs C++ motivés et sérieux pour Last Dungeon.

Chaîne Youtube : Vidéos

Ma page DVP : http://neckara.developpez.com/
Neckara est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 20/11/2012, 13h15   #3
Aleph69
Membre Expert
 
Homme
Chercheur
Inscription : mars 2010
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Chercheur

Informations forums :
Inscription : mars 2010
Messages : 1 143
Points : 1 654
Points : 1 654
Salut,

l'entrée de la faq Peut-on lever des exceptions dans les constructeurs? correspond me semble-t-il à ce que tu cherches.
Aleph69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 13h58   #4
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Merci beaucoup pour vos réponses, mais cela n'indique pas si la valeur de ptA sera encore 0 si il y a eu un problème ; ceci dû au fait qu'elle est initialisée à 0.
En parallèle, je vais regarder (m'instruire ) sur le fonctionnement de l'opérateur new.
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 14h06   #5
cob59
Membre chevronné
 
Inscription : décembre 2008
Messages : 490
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 490
Points : 751
Points : 751
http://en.cppreference.com/w/cpp/mem...w/operator_new

Citation:
3-4) Same as 1-2, but returns a null pointer when 1-2 would throw std::bad_alloc
Donc avec std::nothrow, le new renverra un nullptr (C++11) ou un NULL (C++03), c'est à dire 0.
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 14h10   #6
Aleph69
Membre Expert
 
Homme
Chercheur
Inscription : mars 2010
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Chercheur

Informations forums :
Inscription : mars 2010
Messages : 1 143
Points : 1 654
Points : 1 654
Jette un oeil à Que se passe-t-il si aucun bloc catch n'existe pour traiter une exception?
Si new lance une exception et que tu ne la récupères pas, tu vas sortir de ta fonction en détruisant tous les objets locaux, en l'occurence ptA, et ta question n'a donc pas vraiment de sens.
Si tu préfères, la valeur de ptA ne sera pas modifiée mais sera détruite.
Aleph69 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 14h13   #7
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Merci beaucoup,

j'écris donc
Code :
1
2
3
4
5
 
...
ClasseA * ptA( 0 );
ptA = new( std::nothrow ) ClasseA();
...
et en cas d'erreur d'allocation après le new, ptA vaudra l'adresse 0.

Merci
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 14h17   #8
Aleph69
Membre Expert
 
Homme
Chercheur
Inscription : mars 2010
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Chercheur

Informations forums :
Inscription : mars 2010
Messages : 1 143
Points : 1 654
Points : 1 654
Oui, mais il faut bien noter la subtilité : en cas de problème d'allocation, new renverra le pointeur nul quelle que soit la valeur préalable de ptA. Ce n'est pas le fait d'avoir initialisé ptA à zéro qui provoque ce comportement. Autrement dit, ptA est bien modifié dans ce cas.
Aleph69 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 20/11/2012, 14h25   #9
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Citation:
Envoyé par Aleph69 Voir le message
Oui, mais il faut bien noter la subtilité : en cas de problème d'allocation, new renverra le pointeur nul quelle que soit la valeur préalable de ptA. Ce n'est pas le fait d'avoir initialisé ptA à zéro qui provoque ce comportement. Autrement dit, ptA est bien modifié dans ce cas.
C'est en l'occurrence ce que je veux (pour le moment).
Je reprends du code et il y a à tout bout de champ ce type de chose :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
...
ClasseA * ptA( 0 );
ptA = new ClasseA();
if( !ptA )
    printError();
else
{
    /* utilisation de ptA */
    ...
}
...
je souhaite m'assurer que la vérification du "if" est pertinente.
Merci beaucoup
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 14h28   #10
Aleph69
Membre Expert
 
Homme
Chercheur
Inscription : mars 2010
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Chercheur

Informations forums :
Inscription : mars 2010
Messages : 1 143
Points : 1 654
Points : 1 654
Citation:
Envoyé par MicBeastKiller Voir le message
je souhaite m'assurer que la vérification du "if" est pertinente.
En l'occurence, elle ne l'est pas du tout.
Aleph69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 14h31   #11
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Citation:
Envoyé par Aleph69 Voir le message
En l'occurence, elle ne l'est pas du tout.
C'est bien ce que je pensais.
Et donc cette vérification est pertinente :
Code :
1
2
3
4
5
6
7
8
9
10
11
 
...
ClasseA * ptA( 0 );
ptA = new( std::nothrow ) ClasseA();
if( !ptA )
    printError();
else
{
    ...
}
...
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 14h38   #12
Aleph69
Membre Expert
 
Homme
Chercheur
Inscription : mars 2010
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Chercheur

Informations forums :
Inscription : mars 2010
Messages : 1 143
Points : 1 654
Points : 1 654
Oui, à ceci près que cela ne sert plus à rien d'initialiser ptA à zéro. Dans l'exemple précédent, cela avait du sens car si new levait une exception, alors ptA pouvait être détruit car préalablement initialisé. Ce qui n'avait pas de sens, c'était le test succédant à new.
Aleph69 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 14h49   #13
leternel
Membre Expert
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 175
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : juin 2007
Messages : 1 175
Points : 2 476
Points : 2 476
une autre verification serait
Code :
1
2
3
4
5
6
7
8
9
...
#include <stdexcept>
...
try {
ClasseA * ptA = new ClasseA();
    ...
} catch (const std::bad_alloc& e){
    printError();
}
à une vache près pour le nom de l'exception
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
  • Une variable de moins est une source d'erreur en moins.
  • Un pointeur de moins est une montagne d'erreurs en moins.
  • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 16h24   #14
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Citation:
Envoyé par Aleph69 Voir le message
Oui, à ceci près que cela ne sert plus à rien d'initialiser ptA à zéro. Dans l'exemple précédent, cela avait du sens car si new levait une exception, alors ptA pouvait être détruit car préalablement initialisé. Ce qui n'avait pas de sens, c'était le test succédant à new.
J'ai un peu du mal à suivre.
Dans le premier cas, le fait d'initialiser ptA à 0 permet de garder cette valeur 0 si il y a échec de new ?
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 16h40   #15
leternel
Membre Expert
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 175
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : juin 2007
Messages : 1 175
Points : 2 476
Points : 2 476
Si j'ai bien compris, avec truc = new (std::nothrow) Truc();, tu as l'équivalent (à la portée de truc près) de
Code :
1
2
3
4
5
try {
    truc = new Truc();
} catch (...) {
    truc = std::nullptr;//ou NULL ou 0 ou ... selon la norme et le compilateur
}
Donc, quel que soit la valeur précédente de truc, elle est remplacée.

En tant que telle, truc = new (std::nothrow) Truc(); est une affectation qui réussit systématiquement.

tu n'imagine pas de faire int i = 0; i = f();… le 0 serait inutile.
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
  • Une variable de moins est une source d'erreur en moins.
  • Un pointeur de moins est une montagne d'erreurs en moins.
  • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 16h55   #16
Bousk
Modérateur
 
Homme Cyrille
Network programmer
Inscription : juin 2010
Messages : 1 539
Détails du profil
Informations personnelles :
Nom : Homme Cyrille
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Network programmer

Informations forums :
Inscription : juin 2010
Messages : 1 539
Points : 4 072
Points : 4 072
Citation:
Envoyé par leternel Voir le message
tu n'imagine pas de faire int i = 0; i = f();… le 0 serait inutile.
Inutile si f() retourne 0 en cas d'exception attrapé en interne
Bousk est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 19h05   #17
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Citation:
Envoyé par leternel Voir le message
Si j'ai bien compris, avec truc = new (std::nothrow) Truc();, tu as l'équivalent (à la portée de truc près) de
Code :
1
2
3
4
5
try {
    truc = new Truc();
} catch (...) {
    truc = std::nullptr;//ou NULL ou 0 ou ... selon la norme et le compilateur
}
Donc, quel que soit la valeur précédente de truc, elle est remplacée.

En tant que telle, truc = new (std::nothrow) Truc(); est une affectation qui réussit systématiquement.

tu n'imagine pas de faire int i = 0; i = f();… le 0 serait inutile.
Sauf si la méthode de programmation imposée est :
- toute variable déclarée doit être initialisée avant d'être utilisée.
- tout pointeur déclaré doit être initialisé à 0 avant d'être utilisé.
- l'opérateur new doit être utilisé sur un pointeur préalablement initialisé à 0.
- à la suite de l'opérateur delete sur un pointeur, ce pointeur doit être mis à 0.
- etc.

J'ai par contre toujours cette question en suspend :
Code :
1
2
3
4
5
 
...
ClasseA * ptA( 0 );
ptA = new ClasseA();
...
à la sortie de ce code et si l'allocation a échoué, ptA vaut-il 0 ou autre chose ?

Merci encore à tous .
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 19h43   #18
Emmanuel Deloget
Expert Confirmé Sénior
 
Homme Emmanuel Deloget
Développeur informatique
Inscription : septembre 2007
Messages : 1 826
Détails du profil
Informations personnelles :
Nom : Homme Emmanuel Deloget
Âge : 37
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : septembre 2007
Messages : 1 826
Points : 4 381
Points : 4 381
Citation:
Envoyé par MicBeastKiller Voir le message
Sauf si la méthode de programmation imposée est :
- toute variable déclarée doit être initialisée avant d'être utilisée.
- tout pointeur déclaré doit être initialisé à 0 avant d'être utilisé.
- l'opérateur new doit être utilisé sur un pointeur préalablement initialisé à 0.
- à la suite de l'opérateur delete sur un pointeur, ce pointeur doit être mis à 0.
- etc.
Indépendamment de la méthode de programmation utilisée, le fait de mettre le pointeur à NULL avant l'appel à new() peut être utile dans le cas où tu tu t'attends à des bugs de l'espace. C'est pire si tu compte réinitialiser un pointeur à NULL après le delete.

De manière générale, en C++ le test de la valeur d'un pointeur (enfin, le test == NULL) est souvent signe que le programmeur a fait quelque chose qu'il ne devait pas faire. Dans ce langage, il existe tant de manière de s'assurer qu'un pointeur n'est pas NULL avant de l'utiliser que le test est soit superflu, soit signe d'un manque de compréhension du code ou d'une architecture bancale (comme, par exemple, une mauvaise analyse de la durée de vie d'un objet).

Il faut se rappeler qu'un pointeur appartient à quelqu'un, et ce quelqu'un a une durée de vie. Si l'objet alloué n'a pas la même durée de vie que son propriétaire, alors c'est que ce n'est pas le bon propriétaire.

Citation:
Envoyé par MicBeastKiller Voir le message
J'ai par contre toujours cette question en suspend :
Code :
1
2
3
4
5
 
...
ClasseA * ptA( 0 );
ptA = new ClasseA();
...
à la sortie de ce code et si l'allocation a échoué, ptA vaut-il 0 ou autre chose ?

Merci encore à tous .
ptA == 0 - logique, puisque si new échoue (et lance une exception) alors l'opérateur = n'est pas évalué, donc ptA garde sa valeur originelle.
__________________
[FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.
Emmanuel Deloget est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 19h52   #19
Flob90
Modérateur
 
Avatar de Flob90
 
Homme Florian Blanchet
Etudiant en Optique
Inscription : août 2004
Messages : 1 057
Détails du profil
Informations personnelles :
Nom : Homme Florian Blanchet
Âge : 22
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Etudiant en Optique

Informations forums :
Inscription : août 2004
Messages : 1 057
Points : 2 487
Points : 2 487
La version classique de new lance une exception si il y a un problème (allocation ou construction), si elle n'est pas du tout attrapé, alors le programme termine.

Si l'ensemble déclaration de la variable, appel à new et affectation à la variable est dans un bloc try avec un catch qui attrape cette exception, alors la question ne se pose pas, en cas d'exception une fois attrapée cette variable n'existe plus.
Code :
1
2
3
4
5
6
7
8
9
 
try{
//...
A* p(0);
//...
p = new A(/*param*/);
//...
} catch(/*exceptions*/)
{ /*...*/ }
Si l'ensemble appel à new et l’affectation à la variable est dans dans le try (qui attrape les exceptions concernées), alors l'ordre entre construction et affectation n'étant pas définie, on ne peut rien dire de la valeur de la variable après le bloc catch.
Code :
1
2
3
4
5
6
7
8
9
10
 
A* p(0);
//...
try{
//...
p = new A(/*param*/);
//...
) catch(/*exceptions*/)
{ /*...*/ }
//ici on ne peut rien dire de p.
NB: Dans ce cas ce sont les exceptions provenant des constructeurs qui posent problèmes, si ils ne peuvent lancer, alors la valeur de p sera non nulle.


On peut tricher un peu en utilisant une variable intermédiaire pour "forcer" l'ordre entre la construction et l'affectation à la variable :
Code :
1
2
3
4
5
6
7
8
9
10
 
A* p(0);
//...
try{
//...
A* q = new A(/*param*/);
p = q;
//...
) catch(/*exceptions*/)
{ /*...*/ }
Sans prendre en compte les éventuels optimisations des compilateurs, à la sortie de ce code on a bien p qui vaut 0 ou est associé à l'objet alloué et construit avant.
Malheureusement, il est fort probable que le compilateur optimise un tel code (ie il considère que la variable q ne sert à rien).

NB: Ces morceaux de code n'ont de sens qu'avec les règles de programmation qui te sont imposées, ils ne servent à rien dans un contexte normal (les exceptions font leur boulot).
__________________
"We can solve any problem by introducing an extra level of indirection" Butler Lampson

"N'importe quel problème peut être résolu en introduisant un niveau d'indirection supplémentaire" Butler Lampson (traduction libre)
Flob90 est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 22h00   #20
MicBeastKiller
Membre du Club
 
Inscription : juin 2008
Messages : 120
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 120
Points : 62
Points : 62
Citation:
Envoyé par Emmanuel Deloget Voir le message
C'est pire si tu compte réinitialiser un pointeur à NULL après le delete.
Pourquoi ?

Citation:
Envoyé par Emmanuel Deloget Voir le message
De manière générale, en C++ le test de la valeur d'un pointeur (enfin, le test == NULL) est souvent signe que le programmeur a fait quelque chose qu'il ne devait pas faire. Dans ce langage, il existe tant de manière de s'assurer qu'un pointeur n'est pas NULL avant de l'utiliser que le test est soit superflu, soit signe d'un manque de compréhension du code ou d'une architecture bancale (comme, par exemple, une mauvaise analyse de la durée de vie d'un objet).

Il faut se rappeler qu'un pointeur appartient à quelqu'un, et ce quelqu'un a une durée de vie. Si l'objet alloué n'a pas la même durée de vie que son propriétaire, alors c'est que ce n'est pas le bon propriétaire.
Bien justement et hormis les exceptions, comment vérifier la bonne allocation ?

Citation:
Envoyé par Emmanuel Deloget Voir le message
ptA == 0 - logique, puisque si new échoue (et lance une exception) alors l'opérateur = n'est pas évalué, donc ptA garde sa valeur originelle.
Cela répond donc à ma question. Merci beaucoup.

Citation:
Envoyé par Flob90 Voir le message
La version classique de new lance une exception si il y a un problème (allocation ou construction), si elle n'est pas du tout attrapé, alors le programme termine.

Si l'ensemble déclaration de la variable, appel à new et affectation à la variable est dans un bloc try avec un catch qui attrape cette exception, alors la question ne se pose pas, en cas d'exception une fois attrapée cette variable n'existe plus.
Code :
1
2
3
4
5
6
7
8
9
 
try{
//...
A* p(0);
//...
p = new A(/*param*/);
//...
} catch(/*exceptions*/)
{ /*...*/ }
Si l'ensemble appel à new et l’affectation à la variable est dans dans le try (qui attrape les exceptions concernées), alors l'ordre entre construction et affectation n'étant pas définie, on ne peut rien dire de la valeur de la variable après le bloc catch.
Code :
1
2
3
4
5
6
7
8
9
10
 
A* p(0);
//...
try{
//...
p = new A(/*param*/);
//...
) catch(/*exceptions*/)
{ /*...*/ }
//ici on ne peut rien dire de p.
NB: Dans ce cas ce sont les exceptions provenant des constructeurs qui posent problèmes, si ils ne peuvent lancer, alors la valeur de p sera non nulle.


On peut tricher un peu en utilisant une variable intermédiaire pour "forcer" l'ordre entre la construction et l'affectation à la variable :
Code :
1
2
3
4
5
6
7
8
9
10
 
A* p(0);
//...
try{
//...
A* q = new A(/*param*/);
p = q;
//...
) catch(/*exceptions*/)
{ /*...*/ }
Sans prendre en compte les éventuels optimisations des compilateurs, à la sortie de ce code on a bien p qui vaut 0 ou est associé à l'objet alloué et construit avant.
Malheureusement, il est fort probable que le compilateur optimise un tel code (ie il considère que la variable q ne sert à rien).

NB: Ces morceaux de code n'ont de sens qu'avec les règles de programmation qui te sont imposées, ils ne servent à rien dans un contexte normal (les exceptions font leur boulot).
Je vais donc étudier les exceptions et mettre cela en place.

Merci à tous.
MicBeastKiller est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 23h38.


 
 
 
 
Partenaires

Hébergement Web