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

GTK+ avec C & C++ Discussion :

GtkCurve, erreur d'allocation de memoire


Sujet :

GTK+ avec C & C++

  1. #1
    Membre actif Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Points : 221
    Points
    221
    Par défaut GtkCurve, erreur d'allocation de memoire
    Bonjour,
    J'essai d'afficher une courbe dans une fenetre à l'aide du widget GtkCurve.
    La compilation se passe sans problème, mais lors de l'éxécution, j'ai cette erreur:

    GLib-ERROR **: /build/buildd/glib2.0-2.22.2/glib/gmem.c:136: failed to allocate 4294967276 bytes
    aborting...
    Abandon

    voici mon code:
    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
     
    #include <stdlib.h>
    #include <gtk/gtk.h>
     
    gint main(gint argc, gchar ** argv)
    {
    	/* Variables */
    	GtkWidget * pWindow = NULL;
    	GtkWidget * pCurve = NULL;
    	GtkWidget * pBox = NULL;
    	/* Points de la courbe */
    	gfloat vector[4] = {-8, 0, -2, 7};
     
    	/* Initialisation de gtk */
    	gtk_init(&argc, &argv);
    	pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
    	g_signal_connect(
    			G_OBJECT(pWindow),
    		   	"destroy",
    		   	G_CALLBACK(gtk_main_quit),
    		   	NULL
    			);
     
    	pBox = gtk_vbox_new(TRUE, 10);
    	gtk_container_add (GTK_CONTAINER(pWindow), pBox);
     
    	/* Création d'une courbe */
    	pCurve = gtk_curve_new();
    	gtk_curve_reset (GTK_CURVE(pCurve));
     
    	/* Prarmetrage de l'affichage de la courbe */
    	gtk_curve_set_range(GTK_CURVE(pCurve), -10, 10, -10, 10);
    	gtk_widget_set_sensitive(pCurve, FALSE);
     
    	/* Placement des points de la courbe */
    	gtk_curve_set_vector(GTK_CURVE(pCurve), 4, vector);
     
    	/* Parametrage du type de courbe
    	 * GTK_CURVE_TYPE_SPLINE
    	 * GTK_CURVE_TYPE_LINEAR
    	 * GTK_CURVE_TYPE_FREE
    	 */
    	gtk_curve_set_curve_type(GTK_CURVE(pCurve), GTK_CURVE_TYPE_SPLINE);
     
    	gtk_box_pack_start (GTK_BOX(pBox), pCurve, TRUE, TRUE, 0);
     
    	/* Affichage de la fenetre */
    	gtk_widget_show_all(pWindow);
     
    	/* Demarrage de la boucle evenementielle */
    	gtk_main();
     
    	return EXIT_SUCCESS;
    }
    J'ai cherché sur google, apparement, je ne suis pas le seul à avoir ce probleme, mais je n'ai pas trouvé de réponses

    Donc, si vous avez une petite idée...
    Merci

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Points : 1 633
    Points
    1 633
    Par défaut
    4294967276, c'est -20 quand tu l'interprètes comme un gint. Donc il doit y avoir qquepart uen allocation dont la taille est mal calculée. Je peux pas t'en dire plus.

  3. #3
    Membre actif Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Points : 221
    Points
    221
    Par défaut
    4294967276, c'est -20 quand tu l'interprètes comme un gint.
    Je ne comprends pas trop...

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Points : 1 633
    Points
    1 633
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g_print ("%u %d\n", (guint)4294967276, (gint)4294967276);
    Ca va afficher:

  5. #5
    Membre actif Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Points : 221
    Points
    221
    Par défaut
    C'est curieux, parce que d'apres l'erreur, j'essaie d'allouer 4Go de Ram

    Sinon, ce -20, je ne vois pas d'où il sort, et je ne fais pas d'allocation dynamique

  6. #6
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 293
    Points : 4 943
    Points
    4 943
    Billets dans le blog
    5
    Par défaut
    Je ne connais pas les GtkCurve mais en testant ton code le problème vient de la fonction gtk_curve_set_vector(GTK_CURVE(pCurve), 4, vector);.

    Cette fonction place automatiquement le type de dessin en GTK_CURVE_TYPE_FREE. Regarde le lien de la fonction ci-dessus c'est spécifié dans la doc. Comme tu forces ensuite le type en GTK_CURVE_TYPE_SPLINE, la bibliothèque ne doit plus être à même de fonctionner proprement je suppose.

    Si tu désactives la ligne gtk_curve_set_curve_type(GTK_CURVE(pCurve), GTK_CURVE_TYPE_SPLINE); ton code s'exécute sans problème.

  7. #7
    Membre actif Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Points : 221
    Points
    221
    Par défaut
    Ah, oui, merci

    Mais comment je fais pour changer le type de la courbe alors
    Ils n'en parlent ni dans la doc, ni dans la faq

  8. #8
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Je ne comprends pas pourquoi tu tentes de l'utiliser. Certes, GtkCurve est encore disponible, mais la doc précise tout de même :

    This widget is considered too specialized/little-used for GTK+, and will in the future be moved to some other package. If your application needs this widget, feel free to use it, as the widget does work and is useful in some applications; it's just not of general interest. However, we are not accepting new features for the widget, and it will eventually move out of the GTK+ distribution.
    De plus ce widget est fait pour modifier une courbe de points :
    The GtkCurve widget allows the user to edit a curve covering a range of values. It is typically used to fine-tune color balances in graphics applications like the Gimp
    Pour juste afficher des points ou des courbes, je t'ai déjà dit dans un précédent post que la bonne méthode est de dessiner avec la bibliothèque cairo dans un GtkDrawingArea.

  9. #9
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    J'ai écrit un exemple de ce que tu sembles vouloir faire, en dessinant avec cairo.

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include <gtk/gtk.h>
    #include <math.h>
    #include <cairo.h>
     
    #define WIDTH   640
    #define HEIGHT  480
     
    #define ZOOM_X  100.0
    #define ZOOM_Y  100.0
     
     
    gfloat f (gfloat x)
    {
    	return 0.03 * pow (x, 3);
    }
     
    static gboolean
    on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
    {
    	cairo_t *cr = gdk_cairo_create (widget->window);
    	GdkRectangle da;            /* Dimensions de la GtkDrawingArea */
    	gdouble dx = 5.0, dy = 5.0; /* Nombre de pixels entre chaque point calculé */
    	gdouble i, clip_x1 = 0.0, clip_y1 = 0.0, clip_x2 = 0.0, clip_y2 = 0.0;
    	gint unused = 0;
     
    	/* On définit la zone de clipping, cela correspond à la zone à 
    	 * raffraîchir. En ne dessinant que le strict nécessaire, on dessinera 
    	 * plus rapidement */
    	cairo_rectangle (cr, 
    			event->area.x, 
    			event->area.y, 
    			event->area.width, 
    			event->area.height);
    	cairo_clip (cr);
     
    	/* On détermine les dimensions de la GtkDrawingArea */
    	gdk_window_get_geometry (widget->window, 
    			&da.x, 
    			&da.y, 
    			&da.width, 
    			&da.height, 
    			&unused);
     
    	/* On dessine un fond noir */
    	cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
    	cairo_paint (cr);
     
    	/* On change la matrice de transformation. C'est comme un changement 
    	 * de repère en mathématiques. On centre d'abord l'origine du repère.
    	 * Ensuite on change son échelle */
    	cairo_translate (cr, da.width / 2, da.height / 2);
    	cairo_scale (cr, ZOOM_X, -ZOOM_Y);  
     
    	/* On détermine les points à calculer (c'est à dire ceux se trouvant 
    	 * dans la zone de clipping) */
    	cairo_device_to_user_distance (cr, &dx, &dy);
    	cairo_clip_extents (cr, &clip_x1, &clip_y1, &clip_x2, &clip_y2);
    	cairo_set_line_width (cr, dx);
     
    	/* On dessine les axes */
    	cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
    	cairo_move_to (cr, clip_x1, 0.0);
    	cairo_line_to (cr, clip_x2, 0.0);
    	cairo_move_to (cr, 0.0, clip_y1);
    	cairo_line_to (cr, 0.0, clip_y2);
    	cairo_stroke (cr);
     
    	/* On rajoute les points de la coube en les reliants par une droite */
    	for (i = clip_x1; i < clip_x2; i += dx)
    		cairo_line_to (cr, i, f (i));
     
    	/* On dessine la courbe */
    	cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
    	cairo_stroke (cr);
     
    	cairo_destroy (cr);
    	return FALSE;
    }
     
     
    int
    main (int argc, char **argv)
    {
    	GtkWidget *window;
    	GtkWidget *da;
     
    	gtk_init (&argc, &argv);
     
    	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
    	gtk_window_set_title (GTK_WINDOW (window), "Affichage de courbe");
    	g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
     
    	da = gtk_drawing_area_new ();
    	gtk_container_add (GTK_CONTAINER (window), da);
     
    	g_signal_connect (G_OBJECT (da), 
    			"expose-event", 
    			G_CALLBACK (on_expose_event), 
    			NULL);
     
    	gtk_widget_show_all (window);
    	gtk_main ();
     
    	return 0;
    }

  10. #10
    Membre actif Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Points : 221
    Points
    221
    Par défaut
    J'avais arrêté d'utiliser cairo, car j'avais du mal à l'utiliser, notament si je voulais parametrer ma fenetre, en introduisant un offset, la courbe ne restait pas en place sur les axes.

    voici le code:
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
     
    #include <gtk/gtk.h>
    #include <math.h>
    #include <cairo.h>
     
    #define WIDTH  640
    #define HEIGHT 640 
     
    #define M_WIDTH  WIDTH/2
    #define M_HEIGHT HEIGHT/2
     
    gfloat sinusoide(gfloat x)
    {
    	gfloat y =  220 * sin (0.03 * x);
    	return y;
    }
     
    	static void
    repere_initialize(cairo_t *cr, gint x_offset, gint y_offset)
    {
    	gint i = 0;
     
    	/* Initialisation du repere */	
    	cairo_set_line_width(cr, 1);
    	cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
     
    	/* Dessin des axes x et y */
    	cairo_move_to(cr, x_offset, -M_HEIGHT + y_offset);
    	cairo_line_to(cr, x_offset, M_HEIGHT + y_offset);
    	cairo_stroke(cr);
     
    	/* Decalage du repere */
    	cairo_move_to(cr, -6000, y_offset);
    	cairo_line_to(cr, 6000, y_offset);
    	cairo_stroke(cr); 
     
    	/* Initialisation de le couleur et de
    	 * l'épaisseur de la courbe
    	 */
    	cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
    	cairo_set_line_width(cr, 0.5);
     
    }
     
    static gboolean
    expose (GtkWidget * widget, GdkEventExpose * event, gpointer userdata)
    {
    	/* Decalage de la courbe */
    	gint x_offset = 60; 
    	gint y_offset = 0;
     
    	cairo_surface_t *surface = NULL;
     
    	/* Création du contexte */
    	cairo_t *cr = NULL;
     
    	/* Abcisses et ordonées de la courbe */
    	gint x[3] = {
    		-6000,
    		-6000,
    		-6000
    		};
    	gfloat y[3] = { 0 };
     
    	/* Recuperation du context */
    	cr = gdk_cairo_create (widget->window);
    	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
    	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
    	cairo_paint (cr);
     
    	/* Récuperation de la surface */
    	surface = cairo_get_target (cr);
     
    	/* Positionnement du centre du repere */
    	cairo_surface_set_device_offset (surface, WIDTH / 2 + x_offset, HEIGHT / 2 + y_offset);
     
    	/* Initialisation du repere */
    	repere_initialize(cr, x_offset, y_offset);
     
    	while (x[0] <= (M_WIDTH + x_offset))
    	{
    		x[0] = x[2];
    		x[1] = x[0] + 1;
    		x[2] = x[1] + 2;
     
    		/* On calcul y = f(x) tous les trois points */
    		y[0] = sinusoide(x[0]);
    		y[1] = sinusoide(x[1]);
    		y[2] = sinusoide(x[2]);
     
     
    		/* On affiche le morceau de courbe qui
    		 * passe par ces trois points
    		 */
    		cairo_curve_to (cr,
    			       	x[0], -y[0],
    			       	x[1], -y[1],
    			       	x[2], -y[2]
    				);
    	}
    	cairo_stroke (cr);
     
     
    	return FALSE;
    }
     
    gint
    main (int argc, char **argv)
    {
    	GtkWidget *window = NULL;
     
    	gtk_init (&argc, &argv);
     
    	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
    	gtk_window_set_title (GTK_WINDOW (window), "Affichage de courbe");
    	g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
     
    	gtk_widget_set_app_paintable (window, TRUE);
    	g_signal_connect (G_OBJECT (window), "expose-event", G_CALLBACK (expose),
    			    NULL);
     
    	gtk_widget_show_all (window);
    	gtk_main ();
    	return 0;
    }
    Sinon, merci pour le code, je vais l'etudier, et essayer d'ameliorer le mien en conséquence

  11. #11
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Je ne comprends pas grand chose à ton histoire d'offset, mais dans ton exemple, tu travailles en coordonnées pixel, et c'est une grosse erreur...
    Cairo te facilite le boulot avec cairo_translate et cairo_scale, et te permet d'utiliser tes propres unités de manière transparente. En utilisant des coordonnées pixel tu vas forcément te tromper dans les conversions...

    Ah, et tu te trompes dans l'utilisation de cairo_curve_to, seul le 3ème point spécifié est celui qui fait partie du chemin. Les deux autres points passés en paramètre sont les points de contrôle de la courbe de béziers. Donc tu calcules les points 3 par 3 pour rien... Comme je ne sais pas comment on détermine les points de contrôle pour avoir un résultat lisse, j'ai utilisé cairo_line_to avec des points rapprochés. Le tracé reste assez « lisse », ça n'a pas l'air de poser problème.

Discussions similaires

  1. [Sécurité] Erreur d'allocation mémoire
    Par GLDavid dans le forum Langage
    Réponses: 4
    Dernier message: 28/04/2006, 08h34
  2. allocation de memoire pour char**
    Par Guillaume602 dans le forum C++
    Réponses: 3
    Dernier message: 03/04/2006, 20h01
  3. outil permettant de tracker les alloc/dealloc memoire
    Par bob8181_2000 dans le forum C++Builder
    Réponses: 2
    Dernier message: 03/09/2005, 19h57
  4. Allocation de memoire
    Par zakjo_developper dans le forum C
    Réponses: 16
    Dernier message: 08/04/2005, 13h46
  5. char * et Allocation de memoire
    Par venomelektro dans le forum C++
    Réponses: 3
    Dernier message: 14/10/2004, 13h24

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