PROBLEMA Azzerare struct tramite funzione

Pubblicità

Matteo34

Nuovo Utente
Messaggi
104
Reazioni
3
Punteggio
45
Rieccomi qua :)
Ho un problema con le strutture, ho provato a risolvere ma non capisco perché non compili, in pratica devo azzerare una struct(di interi) tramite una funzione, che prende come parametri un puntatore a struttura e la dimensione della struttura da azzerare.
Il primo codice che scrissi fu questo:
C:
int zeroTheStruct(struct_t *struct_pm1, int dim)
{
    if(dim == 0)
    {
        return 0;
    }
    
    while(dim > 0)
    {
        *(struct_pm1+dim) = 0; // non potrebbe compilare
        dim--;
    }
    
    return 1;
}
Mi sono accorto che, giustamente, assegnando un valore a un espressione non compila(anche se non sempre, non ho ancora capito perché).
Allora ho scritto un altro codice:
C:
int zeroTheStruct(struct_t *struct_pm1, int dim)
{
    if(dim == 0)
    {
        return 0;
    }
    
    while(dim > 0)
    {
        struct_pm1 = (struct_pm1 + dim);
        *struct_pm1 = 0; //error 
        dim--;
    }
    
    return 1;
}
Ho pensato di risolvere il problema in questo modo, assegnando il nuovo indirizzo a "struct_pm1" e azzerando il valore puntato da quest'ultimo, così non avrei più assegnato un valore a un espressione,
però mi da il seguente erroe:
Codice:
incompatible types when assigning to type 'struct_t {aka struct <anonymous>}' from type 'int'
Per quale motivo non posso assegnare un intero se l'indirizzo puntato è un intero?
 
Non so come sia composta la struttura, visto che non la riporti.
Comunque per operazioni di questo tipo si utilizza memset.

In generale:
C:
memset(&struttura, 0, sizeof(struttura));
 
Non so come sia composta la struttura, visto che non la riporti.
Comunque per operazioni di questo tipo si utilizza memset.

In generale:
C:
memset(&struttura, 0, sizeof(struttura));
grazie, non ho mai sentito di questa funzione, comunque la struttura e questa:
Codice:
typedef struct{
    int a;
    int b;
    int c;
} struct_t;
potrei sapere perchè il codice non compila?
 
Perchè stai assegnando un intero a una struttura (il tuo parametro è un puntatore al tipo struct_pmi), e i tipi ovviamente sono incompatibili.

Considera che ciò che ti sto mostrando non è da fare, in quanto in questo caso tutti i membri sono di tipo int, ma non vale lo stesso in situazioni generali (e può dipendere da un sacco di fattori).
E' solo per farti un esempio (x86):

C:
    mystruct ms;
    ms.n = 12;
    ms.n2 = 31;
    ms.n3 = 11;
   
    zero_struct(&ms, sizeof(ms)/4);

C:
void zero_struct(mystruct *ms, int dim) {
   
    dim--;
    while(dim >= 0) {
        *((int*)ms+dim) = 0;
        dim--;
    }
}

Questo azzera i membri.
Il cast a int* è per forzare un accesso alla memoria come DWORD (in pratica è un cast a un puntatore di tipo int). Considreando che ogni membro è di 4byte, è sufficiente decrementare 1 ogni volta a dim. Ecco perchè faccio quel /4 (12bytes totali / 4 = 3, tolgo 1 in quanto si va da +0 a +2).
Il codice prodotto infatti è questo:

Codice:
CPU Disasm
Address   Hex dump          Command                                  Comments
00C51009  |.  8945 0C       MOV DWORD PTR SS:[ARG.2],EAX
00C5100C  |>  837D 0C 00    /CMP DWORD PTR SS:[ARG.2],0
00C51010  |.  7C 18         |JL SHORT 00C5102A
00C51012  |.  8B4D 0C       |MOV ECX,DWORD PTR SS:[ARG.2]
00C51015  |.  8B55 08       |MOV EDX,DWORD PTR SS:[ARG.1]
00C51018  |.  C7048A 000000 |MOV DWORD PTR DS:[ECX*4+EDX],0
00C5101F  |.  8B45 0C       |MOV EAX,DWORD PTR SS:[ARG.2]
00C51022  |.  83E8 01       |SUB EAX,1
00C51025  |.  8945 0C       |MOV DWORD PTR SS:[ARG.2],EAX
00C51028  |.^ EB E2         \JMP SHORT 00C5100C
 
Semplicemente non si manipolano i campi di una struttura in questo modo. Perche' non e' portabile. Usa memset.
 
Pubblicità
Pubblicità
Indietro
Top