Qsort su array di puntatori

di il
10 risposte

Qsort su array di puntatori

Mi spiegate perchè questo semplice programma non funziona? Dovrebbe ordinare quest'array di puntatori in base al campo "titolo"... come potete vedere eseguendolo invece non ordina nulla!
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>


typedef struct tipo { char* titolo; int i; } tipo_t;


int compare (const void * p1, const void * p2){

       tipo_t * z1 = (tipo_t*) p1;
       tipo_t * z2 = (tipo_t*) p2;  
       
       return strcmp(z1->titolo,z2->titolo);
}

int main(){
	tipo_t** array = malloc(5*sizeof(tipo_t*));
	int i;
	
	for(i=0;i<5;i++) array[i]=malloc(sizeof(tipo_t));
	
	array[0]->titolo = "vaccc";
	array[1]->titolo = "dksj";
	array[2]->titolo = "pkjio";
	array[3]->titolo = "efwe";
	array[4]->titolo = "jnjn";
	
	qsort(array, 5, sizeof(tipo_t*),compare);
	
	for(i=0;i<5;i++) printf("%s\n", array[i]->titolo);
	
	return 0;
	}
	
	

10 Risposte

  • Re: Qsort su array di puntatori

    Perché allochi un vettore di puntatori che puntano ad elementi della struttura?
    Devi usare un semplice vettore allocato dinamicamente
    
    int main()
    {
       tipo_t *array = (tipo_t*)malloc(5*sizeof(tipo_t));
       int i;
       
       array[0].titolo = "vaccc";
       array[1].titolo = "dksj";
       array[2].titolo = "pkjio";
       array[3].titolo = "efwe";
       array[4].titolo = "jnjn";
       
       qsort(array, 5, sizeof(tipo_t), compare);
       
       for(i=0;i<5;i++) printf("%s\n", array[i].titolo);
       
       return 0;
    }
    
  • Re: Qsort su array di puntatori

    Perchè è una specifica richiesta, se no non avrei specificato che fosse un vettore di puntatori.
  • Re: Qsort su array di puntatori

    Ciao Joker91, ciao Oregon,

    in tal caso dovresti cambiare la tua funzione di compare in quanto quello che ricevi sono array di ptr a struct e non ptr a struct.
  • Re: Qsort su array di puntatori

    Array di ptr a struct? E da dove l'hai dedotto?
  • Re: Qsort su array di puntatori

    Perdonami ma è quello che tu hai definito:
    
    tipo_t** array = malloc(5*sizeof(tipo_t*));
    
    di conseguenza devi cast-are la stessa solfa nella compare:
    
    tipo_t ** z1 = (tipo_t**) p1;
    tipo_t ** z2 = (tipo_t**) p2;
    
    o no?!
  • Re: Qsort su array di puntatori

    ... altrimenti puoi deferenziare in assegnamento ed evitare di farlo nella strcmp:
    
    return strcmp((*z1)->titolo,(*z2)->titolo);
    
    o
    
    return strcmp(z1[0]->titolo,(z2[0]->titolo);
    
    in:
    
    tipo_t * z1 = *(tipo_t**) p1;
    tipo_t * z2 = *(tipo_t**) p2;
    
  • Re: Qsort su array di puntatori

    Ma p1 e p2 sono puntatori alla struct, non ptr a ptr di struct. Quindi il castin come l'avevo fatto io andava bene. p1 è un tipo_t*

    ho castato come dicevi te, con doppio puntatore... e ho deferenziato z1 e z2 nella strcmp.. (*z1)

    Avevi ragione. Ma perchè? non capisco, z1 e z2 sono elementi dell'array e l'array è composto da elementi di tipo_t* ...
  • Re: Qsort su array di puntatori

    Joker91 ha scritto:


    ma p1 e p2 sono puntatori alla struct, non ptr a ptr di struct. Quindi il castin come l'avevo fatto io andava bene. p1 è un tipo_t*
    No, alla qsort hai passato array che è ptr di ptr di struct e la compare ti passa due indirizzi sullo stesso segmento di memoria. E' poi tua discrezione cast-arlo ed eventualmente deferenziarlo per comodità
  • Re: Qsort su array di puntatori

    Appunto, a qsort passo array che e' tipo_t** ma la qsort agira' sugli elementi dell'array che sono tipo_t*... quindi logicamente avrei pensato che p1 e p2 dovessero essere castati come tipo_t*...
  • Re: Qsort su array di puntatori

    Joker91 ha scritto:


    appunto, a qsort passo array che e' tipo_t** ma la qsort agira' sugli elementi dell'array che sono tipo_t*
    NO! Agisce sempre su array perché è giusto che sia così. La comparazione (e lo scambio) avvengono sull'allocazione passata; come cavolo potrebbe sapere che stai passando una tabella di puntatori o un semplice array?! La logica è coerente, ma sei hai ancora dei dubbi usa il tuo gdb metti il break nella compare e guardati gli indirizzi

    Ciao
Devi accedere o registrarti per scrivere nel forum
10 risposte