Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: [C] Array di void*

  1. #1

    [C] array di void*

    Ciao a tutti
    Ho il seguente problema, di cui non riesco a venire a capo.
    Ho un array dichiarato e inizializzato nel seguente modo:
    codice:
    void** array;
    array=(void**)malloc((sizeof(void*))*capacitaIniziale);
     for(i=0;i<capacitaIniziale;i++)
           	  array[i]=NULL;
    Ora, ho un altro array uguale, sempre di tipo void**, e voglio uguagliare gli elementi. Ponendo di mettere degli interi all'interno degli array, insomma, vorrei copiare ad esempio tutti (i valori de)gli elementi del secondo array in quello del primo.

    Il problema sorge qui: nel ciclo, come va scritta l'uguaglianza?
    codice:
    array[i]=array2[i];
    Sicuramente ci va un cast di qualche tipo..ma le ho provate di tutti i colori ma niente da fare.
    E sicuramente è tutta colpa dei void* che incasinano

  2. #2
    beh certo devi eseguire un cast.
    come fa il compilatore a copiare una cosa di cui non sa la dimensione?

    cmq la funzione non funziona

    codice:
    void** array;
    array=(void**)malloc((sizeof(void*))*capacitaIniziale);
     for(i=0;i<capacitaIniziale;i++)
           	  array[i]=NULL;
    con sizeof(void*) il compilatore fa errore oppure ritorna 0 (il che ovviamente non va bene)
    la tua funzione dovrà avere anche un parametro con il quale gli dici la dimensione del singolo componente dell'array.

  3. #3
    Ah ecco, non avevo pensato a quello Però volendo lasciare un tipo "generico" come posso stabilire la dimensione di quel void*? Cioè, come posso sapere a priori che dimensioni dargli?

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da Lasentinella
    Ah ecco, non avevo pensato a quello Però volendo lasciare un tipo "generico" come posso stabilire la dimensione di quel void*? Cioè, come posso sapere a priori che dimensioni dargli?
    se ho capito bene la domanda (il che non è scontato) normalmente è 1 (1 byte).

    sostanzialmente stai definendo un vettore di byte

  5. #5
    se non gli passi un parametro con la dimensione dell'unità, allora devi accedere al vettore come se vosse di un byte per forza, oppure di 2 o di 4 come vuoi tu ma se poi è un'array di char?

    se per esempio c'è una funzione che ne ritorna un elemento, sarà simile

    void* getElement (void* src, int elemsize, int elempos) {
    void* t = malloc(elemsize);
    memcpy(src+(elempos*elemsize), t, elemsize);
    return t;
    }

    {
    /* l'elemento è un long */

    long el;
    long* array = (long*)malloc(10*4);
    el = *(getElement(array, 4, 0);
    }

  6. #6
    Originariamente inviato da Lasentinella
    Ah ecco, non avevo pensato a quello Però volendo lasciare un tipo "generico" come posso stabilire la dimensione di quel void*? Cioè, come posso sapere a priori che dimensioni dargli?
    Quando nell'allocazione di memoria utilizzi la dimensione di un puntatore ad un oggetto di tipo void, cioè sizeof(void *), questa ti restuituirà la dimensione di un qualsiasi puntatore. Ovvero 4 byte per sistemi a 32bit e 8 byte per sistemi a 64bit.

    codice:
    array=(void**)malloc((sizeof(void*))*capacitaIniziale);
    Stai creando un vettore di puntatori, non un array di caratteri. Quei puntatori sono indirizzi di memoria che potranno essere poi eventualmente sovrascritti per puntare a dati di tipo voluto.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Una cosa come array[i] non potrebbe mai funzionare se array è dichiarato di tipo void **.
    every day above ground is a good one

  8. #8
    Ah bene, ho capito...quindi, non potendo usare array[i], rifacendomi all'esempio di lolide potrei copiare il contenuto di un array nell'altro in questo modo?

    codice:
    -ciclo- 
    {
      memcpy(biggerOne+(i+elemsize), smallOne+s, elemsize);
      i++;
      s++;
    }
    (in ogni caso ho provato successivamente a fare un printf("%d ",*(int*)biggerOne+i); per vedere se stampa l'int ma invece mi stampa un numero enorme )

  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Sinceramente, tanto per cominciare, non capisco perché definisci un array di tipo void **. Cioè vuoi che sia un array di puntatori void e non semplicemente un array di tipo void? Prova a contestualizzare meglio il problema... cosa vuoi fare? Hai per caso un array di tipo int che vuoi trattare come array generico?

    Poi vedi se questo snippet ti può essere d'aiuto (è un po' rozzo, l'ho scritto al momento senza tanta cura ma funziona, almeno con gcc 4.4.4).

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
    	void *a, *tibet;
    	int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    	int i;
    
    	a = malloc(10 * sizeof(int));
    	if (a == NULL) {
    		fprintf(stderr, "Fail.\n");
    		return -1;
    	}
    
    	memcpy(a, array, 10 * sizeof(int));
    
    	for (i = 0; i < 10; i++) {
    		printf("%d\n", *((int *)a + i));
    	}
    
    	tibet = malloc(10 * sizeof(int));
    	if (tibet == NULL) {
    		fprintf(stderr, "Adieu, monde cruel.\n");
    		return -1;
    	}
    
    	memcpy(tibet, a, 10 * sizeof(int));
    
    	for (i = 0; i < 10; i++) {
    		printf("%d\n", *((int *)tibet + i));
    	}
    
    	free(a);
    	free(tibet); /* http://www.freetibet.org/ */
    
    	return 0;
    }
    every day above ground is a good one

  10. #10
    Intanto ringrazio te e tutti gli altri che mi hanno risposto (anche per i pezzi di codice, utilissimi ), perché mi state aiutando a chiarire un po' le idee (che, per quanto riguarda i puntatori, non sono mai abbastanza chiare) e soprattutto a proseguire col programma...

    Ho usato un void** perché ho ripreso le indicazioni del prof. che nelle slide mostra una struttura definita così (che in effetti usa una pila con riferimento al prossimo elemento e non un array):
    codice:
    struct struct_pila {
     void** elements; // contiene gli elementi della pila 
    int next; // indice dove inserire il prossimo elemento
    int capacity; // lunghezza dell’array elements 
    };
    Anche se cercando qui e là ricordo di aver letto una persona che diceva ad un'altra "non è il caso di dichiararlo void**, basta void* per fare un array di generici, altrimenti crei un array di array"

    Ho un'altra domanda, sempre relativa a tutto ciò (penso l'ultima ):
    vorrei creare un metodo toString() che crei una stringa con l'elenco degli elementi contenuti nell'array. Siccome void* necessita un cast, ma io non so se l'utente metterà un char o un int/long/..., dite che c'è modo di farlo? Utilizzando un metodo solo e senza passare come argomento una variabile che identifichi il tipo.
    Per rispiegare meglio:
    - L'utente nell'array inserisce degli interi, chiama il toString(array) (senza specificare con altri parametri cosa contiene l'array) e stampa la stringa ottenuta.
    - L'utente crea un array in cui inserisce dei char e sempre col toString(array) ottiene un'altra stringa.

    Cercando su google ho trovato che non è possibile farlo in quanto non c'è una funzione che "dica" di che tipo è il void che utilizzo...
    E allora mi chiedevo il consiglio del professore "Stampate il valore del puntatore (piu' meno la stessa cosa che fa la toString() di Object in Java)." come fa a creare la stringa giusta

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.