Flux rss
Rechercher : dans
Par : Mots clés Nom d'utilisateur
Messages sans réponse

Operator et pointeur [C++]

Char Snipeur, le lundi 3 mai 2004 à 17:31:43 
 Signaler ce message aux modérateurs

Bonjour, je fait une classe Matrix, defini comme ça :
struct Matrix{vector<double>M;}
pour définir l'opérateur multiplier :
Matrix& operator*(matrix& A, Matrix& B)
{matrix *tmp;
tmp=new matrix;
// calculs du produit que je vous épargne
return *tmp;}
voila l'algorithme de base. Le programme parfaitement, mise à par une ENORME fuite de mémoire qui est du au fait que tmp ne soit pas détruit à la fin de l'apel de la fonction.
Je ferai bien la declaration de tmp en non-pointeur, mais le compilateur me dit que je retourne un variable local. Et si j'enleve les "&" , le compilateur n'est pas content non plus, ou alors le programme plante pour violation d'acces.
Je sais que le problème n'est pas facile, mais la je seche...
Si quelqu'un pouvait m'aider, je lui en serai très reconnaisant.
Merci

Salutation !
Char Snipeur

1

blurk, le mardi 4 mai 2004 à 09:04:48

Dans le constructeur de matrix, tu peux mettre un new, il y a même
moyen( de passer un paramètre pour la taille d'allocation lors de la déclaration d'une instance de matrix.
matrix(1) *a; avec un new dedans. (1 à multiplier par sizeof de matrix dans le constructeur)
et dans le destructeur le delete[]
Les constructeurs par défaut servent surtout à ça.

autrement, je sais qu'il n'est pas interdit de faire de l'allocation statique:
Matrix& operator*(matrix A[2], Matrix B[2] );
le compilateur se débrouille tout seul pour l'allocation.
Je sais pas si c'est la solution, mais il y a sûrement encore d'autres moyens.

a+

Répondre à blurk

2

Char Snipeur, le mardi 4 mai 2004 à 09:48:35

Merci de ta réponse blurk. Je n'ai pas tout compris surtout car j'ai toujours essayer d'éviter les new et delete. Je ne sais pas très bien comment ils fonctionnent... Je vais me renseigner.
en fait pour l'opérateur, les "&" dans l'apel, si je ne les met pas, j'ai des erreurs de calcul : le passage par valeur se fait rès mal. En plus il me parait un peu restrictif de donnée une taille de matrice dans l'appel "matrix A[2]" si je fait une matrice plus grande, je fait comment?

Salutation !
Char Snipeur

Répondre à Char Snipeur

3

marvirouge, le mercredi 26 mai 2004 à 17:04:06

Matrix& operator*(matrix& A, Matrix& B)

l'opérateur * doit retourner *this et pas un objet temporaire alloué !

Répondre à marvirouge

4

marvinrouge, le mercredi 26 mai 2004 à 17:06:01

Oups désolé je viens de dire une grosse BETISE.
c'est la fatigue.
j'arretes de bosser, je rentre chez moi et je corrige ce code demain ...

Répondre à marvinrouge

5

marvinrouge, le mercredi 26 mai 2004 à 17:37:37

Je reviens après 10 cafés, ça va mieux

Conventions classiques C++
- l'opérateur * rend Matrice
- l'opérateur *= rend une Matrice*
-ils prennent tous les 2 un seul paramètre

donc
Matrice& operator*=(matrix& b)
{
return *this = *this * b; // ici il FAUT que l'opérateur = existe ET on se sert de l'opérateur * écrit ci dessous
}

Matrice operator*(matrix& b) {
Matrice c(this->getNbLigs(), this->getNbCols());
//remplissage de c
return c; // ici il FAUT que le constrcuteur de copie existe
}

tu dois définir aussi

Matrice& operator=(matrix& b) { // opérateur d'affetatiion
// ...
}

Matrice(matrix& b) { // constrcuteru de copie
// ...
}


est-ce clair ?

marvinrouge

Répondre à marvinrouge

6

Benur29, le mercredi 24 janvier 2007 à 21:18:10

Bien que la discussion soit terminée depuis belle lurette, je la complète pour éclairer d'autres esprits

si on déclare ainsi alors on doit retourner *this :
Matrice& operator*=(matrix& b)
{
return *this = *this * b; // ici il FAUT que l'opérateur = existe ET on se sert de l'opérateur * écrit ci dessous
}


par contre si on déclare de la façon qui suit, on peut retourner une valeur construite dans la fonction membre :
Matrice& operator*=(matrix& b) const
{
Matrice* resultat = new Matrice(param_d-init-du_constructeur);
.....
return *resultat
}

En espérant vous éclairer

Répondre à Benur29

7

Char Snipeur, le jeudi 25 janvier 2007 à 08:54:36
  • +1

Salut.
Après des tests, et vue que j'ai apris un peu mieux le C++.
Le mieux est d'utiliser :
Matrix operator*(Matrix& A, Matrix& B);
cette fonction est défini en dehors de la class, c'est une surcharge de l'opérateur binaire '*'
J'ai enlever le '&' dans le retour de la fonction, car c'est la valeur qui nous intéresse, il n'y a aucune utilité de modifier A*B (A*B=6 n'a pas de sens en affectation) J'ai mis des '&' dans les paramètres de la fonctions pour passer les références des objets, car cela évite les erreurs de recopie et gagne du temps de recopiage des objets.
daccord sur la fonction membre 'operator*=' elle est parfaite.
en revanche la fonction 'matrix& operator*(matrix& b)' génère toujours des fuites de mémoire car la matrice resultat n'est jamais détruite. Dans ce cas, il est possible (3 matrice A,B et C) de faire :
A*B=C, resultat prend la valeur de C par l'opérateur '=' mais A et B ne sont pas modifier. et à chaque fois que tu fera A*B tu créra une nouvelle variable resultat . Salutation !
Char Snipeur

Répondre à Char Snipeur

8

Benur29, le jeudi 25 janvier 2007 à 17:31:40

La solution :

matrix& operator*(matrix& b)const
{
matrix* result = new matrix(.......);

...........

return = *result;
}

mais bon fais comme tu le sens hein ..........lol

bon amusement

Répondre à Benur29

9

Char Snipeur, le vendredi 26 janvier 2007 à 09:31:17
  • +1

Je maintient, ta solution n'es pas bonne car elle engendre une fuite de mémoire, et aussi pour les raisons exposés dans le messsage précédent. Salutation !
Char Snipeur

Répondre à Char Snipeur

10

mamiemando, le vendredi 26 janvier 2007 à 10:14:55
  • +1

Tout à fait d'accord avec charsniper mais en fait c'est presque bon :

matrix operator*(matrix& b)const {
  matrix result(.......); 
   //...
  return result
}

En fait si tu calcule A*B tu es effectivement de créer une matrice C=A*B et donc de l'allouer (car tu ne veux modifier ni A, ni B). Cependant qui dit new dit delete, et ici le delete n'était jamais fait (donc la mémoire occupée par C jamais rendue).

Ici tu ne peux pas retourner une référence, ça n'a pas de sens. Retourner une référence n'a de sens que si c'est une variable qui est déjà créée. Typiquement quand tu passes une variable en paramètre, on passe en générale la référence car ça évite de recopier dans la pile la variable passée en paramètre. Ici tu es de toutes façons condamné à créer une nouvelle variable de retour C donc... on la retourne directement :)

Au niveau allocation c'est mieux, car la variable de retour sera déclarée sans new et sera donc automatiquement détruite à la fin du scope ou elle est déclarée :
matrix A,B;
//Initialisation de A et B
//...

// Calcul de C = A*B
{
  int x=69;
  matrix C = A*B;
   //...
} // C est détruite en arrivant à cette accolade au même titre que x

Bonne chance

Répondre à mamiemando

11

 Benur29, le vendredi 26 janvier 2007 à 15:14:18

Ok ; autant pour moi

En ce ki concerne tes fuites memoire : je suppose que tu utilises des tableaux intermédiaires.

si tu les alloues dynamiquement : n'oublie pas de les détruire proprement :

int* tab = new int[n];
....
delete[] tab;


int** tab = new int*[n1]; //tab[n1][n2]
for(int j= 0; j<n1 ; j++)
{
tab[j] = new int[n2];
for(int h=0; h<n2 ; h++)
{
tab[j][h] = .........;
}
}
......
for(j= 0; j<n1 ; j++)
{
delete[] tab[j];
}

delete[] tab;

avec ça c propre

Répondre à Benur29
Probleme de redefinition d'operator en C++ Bonjour je developpe un projet en C++ et j'ai besoin de redefinir les operateurs de comparaisons je cree ma classe de cette facon : #include #include "sortedvector.h" class reference { private: string mot; sortedvector Pdef;... www.commentcamarche.net/forum/affich-593303-probleme-de-redefinition-d-operator-en-c
Langage C++ - Les pointeurs Comme en langage C, le langage C++ permet d'utiliser des pointeurs pour manipuler des données, mais il introduit aussi le concept de référence, très pratique pour permettre la modification d'une donnée passée en paramètre d'une fonction. Définition... www.commentcamarche.net/contents/cpp/cpppoint.php3
[C++] initialisation dynamique de pointeur Je debute en C++ et je prends en main un code deja existant. Les pointeurs sont pour l instant defini de maniere arbitraire avec une taille maximum bien superieure a nos besoins. J ai donc voulu faire une initialisation dynamique mais je m heurte a... www.commentcamarche.net/forum/affich-1526883-c-initialisation-dynamique-de-pointeur
Les piles en langage CLes piles Requis I. INTRODUCTION II. Définition III. La construction du prototype d'un élément de la pile IV. Opérations sur les piles A. Initialisation B. Insertion d'un élément dans la pile C. Ôter un élément de la pile D. Affichage... www.commentcamarche.net/faq/sujet-8283-les-piles-en-langage-c
JAVA : dll JNI avec pointeur en C#J'ai une dll écrite en C# qui possède des fonctions avec un pointeur en paramètre : Prototype de la fonction dans ma dll JNI typedef unsigned short (__stdcall *TC08_GET_TEMP)(long * temp, unsigned short port, unsigned short channel, unsigned short... www.commentcamarche.net/forum/affich-305278-java-dll-jni-avec-pointeur-en-c
[C++ 64 bits] cast pointeur <-> int (Résolu)Bonjour, J'ai un code qui en gros fait ça : Element T; int f=&T; Element *pT=(Element*) f; ce code ne pose pas de problème en 32 bits, car le int a la même taille que le pointeur (Element*) En revanche, en 64 bits, le pointeur est codé sur plus de... www.commentcamarche.net/forum/affich-5009545-c-64-bits-cast-pointeur-int
[C] pointeurs et passage de paramètresbonjour,je suis en train de relire mes tp de 1ere année et,n'étant pas très douée surtout avec les pointeurs,je rencontre quelques difficultés de compréhension. en effet le but du tp est de chercher le minimum et la maximum dans un tableau avec des... www.commentcamarche.net/forum/affich-3277818-c-pointeurs-et-passage-de-parametres
Télécharger Dev-C++Dev-C++ est un environnement de développement intégré (IDE) en C/C++. Son compilateur est basé sur Mingw de GCC, mais il peut également être utilisé avec CygWin. www.commentcamarche.net/telecharger/telecharger-59-dev-c
Les pointeurs en langage CDéfinition d'un pointeur Un pointeur est une variable contenant l'adresse d'une autre variable d'un type donné. La notion de pointeur fait souvent peur car il s'agit d'une technique de programmation très puissante, permettant de définir des... www.commentcamarche.net/contents/c/cpoint.php3
Langage C - Les listes chaînéesLa notion de structure autoréferrentielle Une structure autoréferrentielle (parfois appelée structure récursive) correspond à une structure dont au moins un des champs contient un pointeur vers une structure de même type. De cette façon on crée... www.commentcamarche.net/contents/c/cliste.php3
Introduction au langage CPetite histoire du C Le langage C a été mis au point par D.Ritchie et B.W.Kernighan au début des années 70. Leur but était de permettre de développer un langage qui permettrait d'obtenir un système d'exploitation de type UNIX portable. D.Ritchie... www.commentcamarche.net/contents/c/cintro.php3