PROBLEMA Azzerare struct tramite funzione

Matteo34

Nuovo Utente
104
3
CPU
i5-10500 3.2Ghz
Dissipatore
Non specificato
Scheda Madre
Non specificata
HDD
M.2 251GB e M.2 500GB
RAM
16GB DDR4 2666mhz
GPU
Grafica Intel® UHD 630
Audio
Non specificata
Monitor
1920x1080 27"
PSU
Non specificato
Case
Non specificato
Periferiche
Nono specificato
Net
Eolo
OS
Ubuntu
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?
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
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));
 

Matteo34

Nuovo Utente
104
3
CPU
i5-10500 3.2Ghz
Dissipatore
Non specificato
Scheda Madre
Non specificata
HDD
M.2 251GB e M.2 500GB
RAM
16GB DDR4 2666mhz
GPU
Grafica Intel® UHD 630
Audio
Non specificata
Monitor
1920x1080 27"
PSU
Non specificato
Case
Non specificato
Periferiche
Nono specificato
Net
Eolo
OS
Ubuntu
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?
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
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
 
U

Utente cancellato 371741

Ospite
Semplicemente non si manipolano i campi di una struttura in questo modo. Perche' non e' portabile. Usa memset.
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili