Contenu | Rechercher | Menus

Annonce

Ubuntu 16.04 LTS
Commandez vos DVD et clés USB Ubuntu-fr !

Pour en savoir un peu plus sur l'équipe du forum.

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

#1 Le 22/03/2007, à 20:31

dialloma

[Resolu] Une petite astuce de C++ (help me)

#include <iostream>
#include <vector>

void f(std::vector<int *>& v);
std::vector<int *> g();
int main (){

	std::cout<<"Test de f -------------->"<<std::endl;
	std::vector<int *> v;
	f(v);
	std::vector<int *>::iterator iterV = v.begin();
	while (iterV!=v.end()){
		std::cout<<**iterV<<std::endl;
		++iterV;
	}

	std::cout<<"Test de g ------------->"<<std::endl;
	std::vector<int *> w;
	w = g();
	std::vector<int *>::iterator iterW = w.begin();
	while (iterW !=w.end()){
		std::cout<<" "<<**iterW<<std::endl;
		++iterW;
	}

	std::cout<<"Test de tmp ------------->"<<std::endl;
	std::vector<int> tmp;
	tmp.push_back(10);
	tmp.push_back(20);
	tmp.push_back(30);

	for (int i=0; i<tmp.size(); ++i){
		std::cout<<" "<<tmp[i]<<std::endl;
	}
	
	return EXIT_SUCCESS;
}


void f(std::vector<int *>& v){
	std::vector<int> tmp;
	tmp.push_back(10);
	tmp.push_back(20);
	tmp.push_back(30);

	std::cout<<"size de tmp "<<tmp.size()<<std::endl;

	int *x = &tmp[0];
	int *y = &tmp[1];
	int *z = &tmp[2];
// 	std::cout<<"1er element "<<*x<<std::endl;
	v.push_back(x);
// 	std::cout<<"1er element "<<*v.front()<<std::endl;
	v.push_back(y);
	v.push_back(z);	
}

std::vector<int *> g(){
	
	std::vector<int> tmp;
	tmp.push_back(15);
	tmp.push_back(20);
	tmp.push_back(30);
		
	int *x = &tmp[0];
	int *y = &tmp[1];
	int *z = &tmp[2];
	
	std::vector<int *> v;
	v.push_back(x);
	v.push_back(y);
	v.push_back(z);	

	return v;
}

Ce bout de code ne m'affiche ce que j'esperait c'est à dire les éléments que j'ai ajouté dans chacun des vecteur.
A l'exécution j'ai:

Test de f -------------->
size de tmp 3
0
20
30
Test de g ------------->
 0
 20
 30
Test de tmp ------------->
 10
 20
 30

et j'espérait avoir

Test de f -------------->
size de tmp 3
10
20
30
Test de g ------------->
 10
 20
 30
Test de tmp ------------->
 10
 20
 30

Pouriez vous m'aider s'il vous plaît ?

Merci

Dernière modification par dialloma (Le 01/04/2007, à 11:09)

Hors ligne

#2 Le 22/03/2007, à 21:26

Luc Hermitte

Re : [Resolu] Une petite astuce de C++ (help me)

Tu as toujours le même genre problème que celui que je t'avais signalé dans l'autre thread. Tu n'alloues rien. Tes pointeurs pointent cette fois vers une zone qui n'existe plus à la sortie de ton fichier.

J'imagine que le côté "pointeur vers int" n'est qu'une simplification de ton véritable code. Dans le cas contraire, tu t'embêtes vraiment pour rien.
Si vraiment t'insistes à avoir des pointeurs, c'est

std::vector<int*> f() {
   std::vector<int*> res;
   res.push_back( new int(42) );
   res.push_back( new int(12) );
   res.push_back( new int(14) );
   return res;
}

qu'il te faut faire.

Mais ... n'oublie pas de libérer tes pointeurs.

#3 Le 23/03/2007, à 09:54

dialloma

Re : [Resolu] Une petite astuce de C++ (help me)

Bonjour Luc Hermitte,
je te remercie neaucoup pour tes aides, elles m'ont beaucoup aider. Effectivement, le coté pointeurs vers int est une simplification de mon code, c'est une structure beaucoup plus complexe. En plus elle est partagé par beaucoup d'autres objets, c'est pourquoi j'utilise des pointeurs. Par ailleurs mes fonctions f et g ne sont que des simplifications d'autres fonctions (je dirai même méthodes f et g). Et les poiteurs vers int (x, y et z) de chacun des fonctions f et g,  pointent vers une case d'un vecteur qui existe déja, mais la seule chose que j'avais oublié, c'est que ce vecteur étais une variable de classe (la classe qui contient f et g), donc visible par toutes les méthodes de la classe, c'est en quelque sorte une variable globale pour chacune des méthodes de la classe contenant f et g. Après reflexion j'ai fais ce code suivant qui m'affiche ce que je veux. Il reste à savoir si il y a une astuce cachée que je ne comprend pas en utilisant ce genre. Je vous remercie pour vos aides. Bonne journée

#include <iostream>
#include <vector>

class Test {
	
	std::vector<int> tmp;
	public:
		Test (){
			tmp.push_back(10);
			tmp.push_back(20);
			tmp.push_back(30);
		}
	
		void f(std::vector<int *>& v);
		std::vector<int *> g();
};

void Test::f(std::vector<int *>& v){

	int *x = &tmp[0];
	int *y = &tmp[1];
	int *z = &tmp[2];

	v.push_back(x);
	v.push_back(y);
	v.push_back(z);
}

std::vector<int *> Test::g(){

	int *x = &tmp[0];
	int *y = &tmp[1];
	int *z = &tmp[2];

	std::vector<int *> v;
	v.push_back(x);
	v.push_back(y);
	v.push_back(z);

	return v;
}


int main (){
	Test t;
	std::cout<<"Test de f -------------->"<<std::endl;
	std::vector<int *> v;
	t.f(v);
	std::vector<int *>::iterator iterV = v.begin();
	while (iterV!=v.end()){
		std::cout<<**iterV<<std::endl;
		++iterV;
	}

	std::cout<<"Test de g ------------->"<<std::endl;
	std::vector<int *> w;
	w = t.g();
	std::vector<int *>::iterator iterW = w.begin();
	while (iterW !=w.end()){
		std::cout<<" "<<**iterW<<std::endl;
		++iterW;
	}

	return EXIT_SUCCESS;
}

Hors ligne

#4 Le 24/03/2007, à 01:17

Luc Hermitte

Re : [Resolu] Une petite astuce de C++ (help me)

Attention à un truc. Au premier redimensionnement de ton vecteur interne, tu peux invalider tous les pointeurs et itérateurs qui se réfèrent à ce vecteur.
=> Tout ce qui a pointé vers ce vecteur, pointera potentiellement ensuite n'importe où -- au premier redimensionnement

#5 Le 24/03/2007, à 01:55

dialloma

Re : [Resolu] Une petite astuce de C++ (help me)

Luc Hermitte, je te remerci encore de nouveau. Effectivement tu as raison, j'ai testé de redimensionner le vecteur, et j'ai effectivement perdu les pointeurs que j'ai déclaré ne pointait plus aux mêmes endroits.
Ma question est que existe t-il un moyen de lutter contre ça. Existe t-il une façon de programmer pour mettre à jour automatiquement ces pointeurs ? Merci d'avance

Hors ligne

#6 Le 24/03/2007, à 03:04

Luc Hermitte

Re : [Resolu] Une petite astuce de C++ (help me)

En jouant avec des proxys peut-être, mais cela risque vite d'être un chouilla complexe.
Je suppose qu'aucun élément ne serait jamais retiré, et je ne garantis pas que cela compile.

struct ElementProxy
{
    typedef std::vector<int> container_type;
    ElementProxy(container_type::size_type ndx, container_type & vec)
    : m_index(ndx), m_vec(vec)
    {}
    container_type::value_type operator*() const {
       return m_vec[m_index];
    }
    container_type::reference operator*() {
       return m_vec[m_index];
    }
    // tu peux aussi envisager de définir l'opérateur -> si tu renvoies des objets
...
private:
    const container_type::size_type m_index;
    container_type                & m_vec;
};
...
std::vector<Elementproxy> Test::g()
{
    std::vector<Elementproxy> res;
    for (std::vector<int>::size_type i =0 ; i!=m_tmp.size() ; ++i)
        res.push_back (ElementProxy(i, m_tmp) );
    return res;
}

Le vecteur renvoyé ne saura pas voir les nouveaux éléments, mais il permettra de voir ceux qui étaient là avant. En cas de retrait, cela plantera.

Une autre option, est de renvoyer un type vue qui ressemble aux std::vector<>, mais qui se comporte comme un proxy vers le vrai vecteur. Par contre attention aux problèmes d'accès concurrents. Il risque de falloir locker des petites choses.

#7 Le 24/03/2007, à 11:38

dialloma

Re : [Resolu] Une petite astuce de C++ (help me)

Merci Luc Hermitte. Je vais garder ton code, je trouve qu'il est pro wink et au besoin je l'exploiterai. Je te remerci pour ta disponibilité.

Bon week - end

Hors ligne