Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 18

Thema: dynamischer Speicher für gtk buttons mit ansiC

  1. #1
    Registrierter Benutzer
    Registriert seit
    08.10.2002
    Beiträge
    8

    dynamischer Speicher für gtk buttons mit ansiC

    Hallo allerseits!

    Ich möchte einer Matix von gtk_widget dynamisch Speicher zuweisen.
    Bisher habe ich eine globaldefinierte Matrix:
    Code:
    static GtkWidget *(button[DIM][DIM]);
    Diese möchte ich nun dynamisch machen. Am besten analog zu meinem Beispiel für eine Integer-Matrix. aus der globalen Matrix
    Code:
    matrix[DIM][DIM]
    ist folgendes geworden:
    Code:
    int **malloc_2D(size_t y, size_t x){
    int **array_2d;
    int *p;
    size_t row;
    
    printf("Anzahl der angeforderten Speicherzellen: %d\n",(x*y*sizeof(**array_2d)+y*sizeof(**array_2d)));
    array_2d=(int **)realloc(matrix, x*y*sizeof(**array_2d)+y*sizeof(**array_2d));
    if(array_2d == NULL){
    	printf("Speicheranforderung fehlgeschlagen\n");
    	return NULL;}
    else{
    	for(row=0, p=(int *)array_2d+y; row<y; row++, p+=x){
    		array_2d[row]=p;}}
    return array_2d;}
    Florian

  2. #2
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    das Problem ist, dass wir hier keinen wirklichen Gtk - Experten haben...

    anda_skoa ist unbestritten für QT (und auch sonst ziemlich alles ;-)) zuständig
    um Java kümmern sich diverse Leute (ich auch)
    aber Gtk - Guru haben wir hier leider keinen...

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  3. #3
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Original geschrieben von peschmae
    das Problem ist, dass wir hier keinen wirklichen Gtk - Experten haben...
    tkortkamp ist GTK+ Entwickler, wenn ich das richtig in Erinnerung habe.

    Außerdem ist das mehr ein C Problem, darum lasse ich es auch in diesem Forum.

    @Florian:
    geht es nicht, wenn du statt int GtkWidget schreibst?

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  4. #4
    Registrierter Benutzer
    Registriert seit
    08.10.2002
    Beiträge
    8
    Ich habe verschiedene Varianten ausprobiert, in denen ich "int" durch "GtkWidget *" ausgetauscht habe. Es gab dabei auch Varianten, bei denen der Compiler keine Warnings ausgespuckt hat. Leider endete bisher alles in einem Segmentation Fault. Aber vielleicht gibt es hier ja einen Pointer-Crack?

  5. #5
    Registrierter Benutzer
    Registriert seit
    16.09.2002
    Beiträge
    73
    Seh' ich das jetzt richtig? Du willst eine Matrix haben, in der die Elemente Pointer auf GtkWidgets sind. Wenn da so ist können wir das ja mal auskaspern.

  6. #6
    Registrierter Benutzer
    Registriert seit
    16.09.2002
    Beiträge
    73
    Ich hab mal was mit ints probiert:

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <malloc.h>
    
    const int dimx = 10;
    const int dimy = 10;
    int **matrix;
    
    int main (void)
    {
    	int x, y, z;
    
    	matrix = (int**)malloc(dimx*dimy*sizeof(int*));
    	if (!matrix){
    		fprintf(stderr,"nicht genug speicher\n");
    		return 1;
    		}else fprintf(stderr,"speicher allokiert\n");
    
    	/* jetzt jedem matrixelement speicher zuordnen */
    	for (x = 0; x < dimx; x++)
    		for (y = 0; y < dimy; y++)
    			matrix[y*dimx + x] = (int*)malloc(sizeof(int));
    
    	/* matrix füllen */
    	z = 0;
    	for (x = 0; x < dimx; x++)
    		for (y = 0; y < dimy; y++)
    			*(matrix[y*dimx + x]) = ++z;
    
    	/* ausgeben */
    	for (x = 0; x < dimx; x++){
    		for (y = 0; y < dimy; y++)
    			printf("%d ", *(matrix[y*dimx + x]));
    		printf("\n");
    		}
    
    	/* speicher freigeben */
    	for (x = 0; x < dimx; x++)
    		for (y = 0; y < dimy; y++)
    			free(matrix[y*dimx + x]);
    	free(matrix);
    
    	printf("fertig\n");
    	return 0;
    }

  7. #7
    Registrierter Benutzer
    Registriert seit
    16.09.2002
    Beiträge
    73
    ...und nun mit einer echten 2d-matrix:

    Code:
    const int dimx = 10;
    const int dimy = 10;
    int ***matrix;
    
    int main (void)
    {
    	int x, y, z;
    
    	matrix = (int***)malloc(dimx*sizeof(int*));
    	for (x = 0; x < dimx; x++)
    		matrix[x] = (int**)malloc(dimy*sizeof(int*));
    
    	fprintf(stderr,"speicher allokiert\n");
    
    	/* jetzt jedem matrixelement speicher zuordnen */
    	for (x = 0; x < dimx; x++)
    		for (y = 0; y < dimy; y++)
    			matrix[y][x] = (int*)malloc(sizeof(int));
    
    	/* matrix füllen */
    	z = 0;
    	for (x = 0; x < dimx; x++)
    		for (y = 0; y < dimy; y++)
    			*(matrix[y][x]) = ++z;
    
    	/* ausgeben */
    	for (x = 0; x < dimx; x++){
    		for (y = 0; y < dimy; y++)
    			printf("%d ", *(matrix[y][x]));
    		printf("\n");
    		}
    
    	/* speicher freigeben */
    	for (x = 0; x < dimx; x++)
    		for (y = 0; y < dimy; y++)
    			free(matrix[y][x]);
    	for (x = 0; x < dimx; x++)
    		free(matrix[x]);
    	free(matrix);
    
    	printf("fertig\n");
    	return 0;
    }

  8. #8
    Registrierter Benutzer
    Registriert seit
    08.10.2002
    Beiträge
    8
    @brotzi: vielen Dank für die Mühe. Ich habe vorhin noch ein wenig rumgebastelt und bin doch noch auf eine Lösung gekommen. Leider ging dann das Internet nicht, so dass ich sie erst jetzt posten kann.

    @all:
    Code:
    static GtkWidget ***button;
    
    GtkWidget ***gtk_malloc_2D(size_t y, size_t x){
    int **array_2d;
    int *p;
    size_t row;
    
    printf("Anzahl der angeforderten Speicherzellen: %d\n",(x*y*sizeof(GtkWidget)+y*sizeof(**array_2d)));
    array_2d=(int **)realloc(buttons, x*y*sizeof(GtkWidget)+y*sizeof(**array_2d));
    if(array_2d == NULL){
      	printf("Speicheranforderung fehlgeschlagen\n");
     	return NULL;}
    else{
     	for(row=0, p=(int *)array_2d+y; row<y; row++, p+=x*12){
      		array_2d[row]=p;}}
    	return GINT_TO_POINTER(array_2d);}
    Ich bevorzuge diese Lösung (abgeguckt von http://www.pronix.de und hoffendlich berichtigt), weil nur einmal Speicher alloziert wird (schnellerer Code) und man trotzdem auf den Inhalt der Matrixelemente mit matrix[y][x] bzw. mit button[y][x] zugreifen kann. Auch wenn der Code etwas kryptisch ist und ich mich dafür vielleicht nochmal verfluchen werde.Falls jemand Fehler findet oder Anregungen hat, bitte posten.

    Florian

  9. #9
    Registrierter Benutzer
    Registriert seit
    25.02.2002
    Ort
    2nd level cache
    Beiträge
    90
    Wäre alles prima, wenn Ihr endlich damit aufhören würdet den Rückgabewert von malloc zu casten!

    Ein void* ist ein universal Pointer!

    den return wert von malloc casten ist zB hier toedlich:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
      char* buffer=(char*)malloc(20);
      strcpy(buffer,"Hallo Welt!");
      printf("%s",buffer);
      free(buffer);
      return 0;
    }
    Tatsächlich gibt's nur auf den Maschinen einen Fehler, deren interne Repräsentation eines 'int'-Wertes von der eines Pointers abweicht.
    In C89 hat aber jede Funktion, die keine Deklaration und keinen Prototyp hat automatisch den Rückgabewert 'int'. Wenn nun ein void* fehlerfrei in einen int und zurück umgewandelt werden kann, ist das ein Problem. Auf 'normalen' Rechnern hat man das Problem (leider) nicht, darum wird dieser Fehler oft gemacht.


    GreetZ

    ReSeT
    Einmal schwarzen Tee mit Milch und Zucker bitte!

  10. #10
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Original geschrieben von ReSeT

    Tatsächlich gibt's nur auf den Maschinen einen Fehler, deren interne Repräsentation eines 'int'-Wertes von der eines Pointers abweicht.
    Was zum Beispiel auf allen 64 Bit Plattformen der Fall ist, da dort ein Pointer 64 Bit lang ist, ein int normalerweise aber wie auf 32 Bit Plattformen nur 32 Bit.

    Kommt auch oft vor, das Leute long Werte auf int zuweisen, weil auf 32 Bit Plattformen zufällig long gleichlang ist wie int.

    Auf 64 Bit Plttformen ist das überlicherweise nämlich auch 64 Bit

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  11. #11
    Registrierter Benutzer
    Registriert seit
    08.10.2002
    Beiträge
    8

    Wink

    Ist ja toll, dass Ihr Euch so gut auskennt!
    Ich kenne mich nicht so gut aus. Für mich wäre an dieser Stelle viel hilfreicher gewesen, wie man es richtig macht. Das TÖTLICHE Beispiel sagt mir zwar, dass ich das wohl nicht sicher auf anderen Plattformen laufen lassen kann, hilft aber irgendwie nicht weiter.
    Wenn jemand eine plattformunabhängige Variante meiner Funktion posten könnte und mir nicht nur zwischen den Zeilen mitteilt: "Du hast ja wohl überhaupt keine Ahnung", wäre ich sehr erfreut.
    Florian
    Geändert von Florian (16-03-2003 um 15:45 Uhr)

  12. #12
    Registrierter Benutzer
    Registriert seit
    16.09.2002
    Beiträge
    73
    @ReSeT: was soll der Quatsch? Ein char* ist genauso groß wie ein int* oder ein void* auf allen Systemen! Wenn man ein malloc macht wird lediglich die angegebene Anzahl bytes allokiert und die Adresse zurückgegeben. Unabhängig von Endianess oder sonstwas! Falsch wäre es natürlich aus einem char* ein int* zu casten wenn man nicht auf die Endianess achtet.

    Größen von int usw. haben wir beide übrigens mit sizeof() beachtet, sodaß der cast erlaubt ist!
    Geändert von brotzi (16-03-2003 um 16:30 Uhr)

  13. #13
    Registrierter Benutzer
    Registriert seit
    25.02.2002
    Ort
    2nd level cache
    Beiträge
    90
    @Brotzi: Ich weise hier nur auf Unnötigkeiten hin, die man schlichtweg weglassen kann, ich habe mich über dieses Problem schon mehrfach in Foren rumgestritten und werde es hier nicht wieder tun.

    Tatsächlich gibt's nur auf den Maschinen einen Fehler, deren interne Repräsentation eines 'int'-Wertes von der eines Pointers abweicht.
    @Florian: Lass einfach den Cast weg und binde die stdlib.h ein, dann ist alles gut.

    und mir nicht nur zwischen den Zeilen mitteilt: "Du hast ja wohl überhaupt keine Ahnung",
    Wenn Du das so verstanden hast, es war jedenfalls nicht meine Absicht, das so rüberkommen zu lassen.


    GreetZ

    ReSeT
    Einmal schwarzen Tee mit Milch und Zucker bitte!

  14. #14
    Registrierter Benutzer
    Registriert seit
    08.10.2002
    Beiträge
    8
    Ähm...
    Auf das komische Casten bin ich ja erst gekommen, weil ich sonst die folgende Fehlermeldung erhalte:

    gcc `gtk-config --libs --cflags` -Wall -pedantic -ansi gtk_puzzle-0.8.c -o gtk_puzzle
    gtk_puzzle-0.9.c: In function `gtk_malloc_2D':
    gtk_puzzle-0.9.c:38: warning: return from incompatible pointer type

    38: return array_2d;}

    Wie gehts denn nun????????

    Florian

    (stdlib.h ist übrigens eingebunden)

  15. #15
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    p und array_2d sind noch int anstatt GtkWidget

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •