[C] Eliminazione elemento da array e riallocazione

Messaggioda ZfreS » 22/07/2021, 20:28

Buonasera. Sto avendo un problema col c. Devo scrivere una funzione a cui viene passato un array allocato dinamicamente nel main e un intero che indica la posizione di un elemento che va cancellato. Inoltre l'array deve ridimensionarsi, rilasciando una locazione di memoria non più occupata. Il codice che ho scritto però non funziona.
Sapreste aiutarmi a capire il problema, o un modo migliore di risolvere? Grazie in anticipo!

Codice:
#include <stdlib.h>
void eliminaElemento(int lista[], int posizione, int size)
{
    int*listaProvvisoria = (int*) malloc((size - 1) * sizeof(int));
    for(int i = 0; i < posizione; i++)
        listaProvvisoria[i] = lista[i];
    for(int i = posizione + 1; i < size; i++)
        listaProvvisoria[i] = lista[i];

    *lista= (int*) realloc(lista, (size- 1) * sizeof(int) );
    for(int i = 0; i < size - 1; i++)
        lista[i] = listaProvvisoria[i];
}

void stampaLista(int lista[], int size)
{
    for(int i = 0; i < size; i++)
        printf("\n %d", lista[i]);
}

int main(void)
{
    int size = 10;
    int posizione = 3;
    int *lista = (int *) malloc(size * sizeof(int));
    stampaLista(lista, size);
    eliminaElemento(lista, posizione, size);
    stampaLista(lista, size - 1);
}
[URL=https://datesnow.life]Authentic Ladies[/URL]
ZfreS
Cannot live without
Cannot live without
 
Messaggio: 2211 di 4590
Iscritto il: 22/10/2016, 17:52
Località: Usa

Re: [C] Eliminazione elemento da array e riallocazione

Messaggioda vict85 » 23/07/2021, 10:44

La riallocazione è esplicitamente richiesta dal professore? Insomma, in genere non si rialloca quando si cancellano pochi dati. In genere, ci si limita a dichiarare che la dimensione è cambiata.

Inoltre la definizione della funzione è strana: passi come array qualcosa che vuoi modificare e non fornisci la nuova dimensione a chi usa la funzione.
vict85
Moderatore
Moderatore
 
Messaggio: 10448 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C] Eliminazione elemento da array e riallocazione

Messaggioda vict85 » 23/07/2021, 11:36

Comunque il tuo codice non assegnava alcun valore a lista.

Comunque, io mi sarai limitato a qualcosa come:
Codice:
#include <stdlib.h>
#include <stdio.h>

int
eliminaElemento( int lista[], int posizione, int size )
{
    if ( posizione >= size )
        return size;

    for ( int i = posizione + 1; i < size; i++ )
        lista[ i - 1 ] = lista[ i ];

    return size - 1;
}

void
stampaLista( int lista[], int size )
{
    for ( int i = 0; i < size; i++ )
        printf( "%d ", lista[ i ] );

    printf( "\n" );
}

void
inserisciValori( int lista[], int size )
{
    for ( int i = 0; i < size; i++ )
        lista[ i ] = i;
}

int
main( void )
{
    int size = 10;
    int posizione = 3;
    int* lista = (int*)malloc( size * sizeof( int ) );
    inserisciValori( lista, size );
    stampaLista( lista, size );
    size = eliminaElemento( lista, posizione, size );
    stampaLista( lista, size );
}


Mentre se devi proprio riallocare, allora devi passare un puntatore all'array (devi modificare il valore del puntatore). Ci ho provato senza, ma il mio address sanitaser non apprezzava.
Codice:
#include <stdlib.h>
#include <stdio.h>

int
eliminaElemento( int** lista, int posizione, int size )
{
    if ( posizione >= size )
        return size;

    for ( int i = posizione + 1; i < size; i++ )
        ( *lista )[ i - 1 ] = ( *lista )[ i ];

    *lista = (int*)realloc( *lista, ( size - 1 ) * sizeof( int ) );
    return size - 1;
}

void
stampaLista( int lista[], int size )
{
    for ( int i = 0; i < size; i++ )
        printf( "%d ", lista[ i ] );

    printf( "\n" );
}

void
inserisciValori( int lista[], int size )
{
    for ( int i = 0; i < size; i++ )
        lista[ i ] = i;
}

int
main( void )
{
    int size = 10;
    int posizione = 3;
    int* lista = (int*)malloc( size * sizeof( int ) );
    inserisciValori( lista, size );
    stampaLista( lista, size );
    size = eliminaElemento( &lista, posizione, size );
    stampaLista( lista, size );
}
vict85
Moderatore
Moderatore
 
Messaggio: 10449 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C] Eliminazione elemento da array e riallocazione

Messaggioda Super Squirrel » 23/07/2021, 12:06

Alcune osservazioni:

- il problema non è che non funziona, ma che non compila, in quanto stai cercando di assegnare un puntatore ad una variabile intera:
Codice:
*lista = (int*) realloc(lista, (size - 1) * sizeof(int));

- il secondo for nella funzione eliminaElemento() è sbagliato e andrebbe corretto, per esempio, nel seguente modo:
Codice:
for(int i = posizione + 1; i < size; i++)
    listaProvvisoria[i - 1] = lista[i];

- inoltre, dal momento che dalla documentazione della realloc() si legge
The function may move the memory block to a new location (whose address is returned by the function).

è sbagliato passare il parametro lista per copia;
- la funzione eliminaElemento() dovrebbe occuparsi anche di aggiornare il valore di size;
- sarebbe buona norma liberare la memoria allocata in precedenza;
- listaProvvisoria è superfluo, basta spostare gli elementi a partire da posizione;
- chiamare un array dinamico lista mi sembra un po' ambiguo.

Sulla base di quanto appena detto il codice diventa:
Codice:
#include <stdlib.h>
#include <stdio.h>

void elimina_elemento(int **v, int *size, int posizione)
{
    for(int i = posizione + 1; i < *size; ++i)
    {
        (*v)[i - 1] = (*v)[i];
    }
    *v = (int*)realloc(*v, --(*size) * sizeof(int));
}

void stampa_array(int *v, int size)
{
    for(int i = 0; i < size; ++i)
    {
        printf("%d ", v[i]);
    }
    printf("\n");
}

int main()
{
    int size = 5;
    int *v = (int *)malloc(size * sizeof(int));
    stampa_array(v, size);
    elimina_elemento(&v, &size, 2);
    stampa_array(v, size);
    free(v);
}


Inoltre, a meno che tu non sia obbligato a farlo per esigenze particolari, non ha molto senso riallocare la memoria ogni volta, basta associare all'array dinamico una dimensione massima e una dimensione utilizzata.


EDIT:
Preceduto
Chi dorme in democrazia, si sveglia in dittatura.
Super Squirrel
Senior Member
Senior Member
 
Messaggio: 698 di 1486
Iscritto il: 16/05/2013, 22:05

Re: [C] Eliminazione elemento da array e riallocazione

Messaggioda ZfreS » 23/07/2021, 17:43

Grazie mille a tutti per l'aiuto. La soluzione che ha fornito super squirrel è quella che si adatta meglio al mio caso.
Grazie ancora a tutti!
[URL=https://datesnow.life]Authentic Ladies[/URL]
ZfreS
Cannot live without
Cannot live without
 
Messaggio: 2212 di 4590
Iscritto il: 22/10/2016, 17:52
Località: Usa


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite