Torna indietro   Hardware Upgrade Forum > Software > Programmazione

DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici
DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici
DJI porta un importante aggiornamento alla sua linea di gimbal camera tascabili con Osmo Pocket 4: sensore CMOS da 1 pollice rinnovato, gamma dinamica a 14 stop, profilo colore D-Log a 10 bit, slow motion a 4K/240fps e 107 GB di archiviazione integrata. Un prodotto pensato per i creator avanzati, ma che convince anche per l'uso quotidiano
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Il primo headset open-back della linea INZONE arriva a 200 euro con driver derivati dalle cuffie da studio MDR-MV1 e un peso record di soli 199 grammi
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA
Al .NEXT 2026 di Chicago, Nutanix ha mostrato quanto sia cambiata: una piattaforma software che gestisce VM, container e carichi di lavoro IA ovunque, dall’on-premise al cloud pubblico. Con un’esecuzione rapidissima sulle partnership e sulla migrazione da VMware
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 19-08-2018, 23:25   #1
vicko98
Junior Member
 
Iscritto dal: Aug 2018
Messaggi: 4
Su linux funziona, su Windows no [C]

Salve,

mi sto preparando per un esame universitario basato sul linguaggio C.
Ho svolto una traccia di qualche esame fa in cui veniva chiesto di creare una lista con una sottolista annidata, inserendo prima i dati nella lista principale in maniera ordinata, mentre nella sottolista è richiesto un inserimento in coda.

il testo è questo:
Quote:
Un servizio di assistenza clienti utilizza un archivio informatico in cui gli interventi di assistenza
vengono organizzati in funzione del nome del quartiere in cui si deve effettuare l'intervento. In
particolare, la struttura dati utilizzata include una lista che contiene le seguenti informazioni:

Nome Quartiere
Coda degli interventi

Dove il campo Nome Quartiere specifica il nome di uno dei quartieri in cui è divisa la città in cui
opera il servizio di assistenza.
La lista è realizzata con puntatori ed è ordinata per Nome di Quartiere.
Per ogni elemento della lista, oltre al campo Nome Quartiere, è memorizzata la coda degli
interventi. Tale coda contiene tutti gli interventi da eseguire in ciascun quartiere, memorizzati in
ordine temporale di arrivo. Ciascun elemento della coda degli interventi contiene i dati del
cliente che ha richiesto l’intervento di assistenza, e cioè:

Cognome
Nome
Via
Telefono
Tipo di Intervento Richiesto
Descrizione dell'intervento richiesto

La coda degli interventi è realizzata con puntatori.
Il tipo di intervento è codificato con un opportuno codice definito tramite enum
Codificare in Linguaggio C:

 le strutture dati utilizzate;
 una procedura di inserimento di un nuovo quartiere (non presente in archivio);
 una procedura di inserimento di una richiesta di intervento. Se il quartiere non esiste, viene
inserito in archivio;
 una procedura che indichi il numero di interventi per ciascun quartiere;
 una procedura che riceve in ingresso il nome di un quartiere e che in uscita fornisce tutti i dati
del primo intervento presente in coda per quel quartiere. Tale richiesta viene quindi eliminata
dalla coda;
 Il main che richiama opportunamente le procedure precedenti.

Durata della prova: 2 ore
il codice è questo:

Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
enum tipo {inst,exe,test};
struct intervento
{
    char cognome[20];
    char nome[20];
    char via[30];
    char telefono[15];
    enum tipo t;
    char info[30];
    struct intervento *next;
};
struct quartiere
{
    char nomehq[20];
    struct intervento *act;
    struct quartiere *next;
};
void inshq(struct quartiere** list)
{
    struct quartiere *p,*g,*t=*list,*scorri=*list;
    int status=0;
    p=(struct quartiere*)malloc(sizeof(struct quartiere));
    p->next=NULL;
    //p->act=(struct intervento*)malloc(sizeof(struct intervento));
    //p->act->next=NULL;
    printf("Inserisci un nome di un quartiere: ");
    scanf("%s",p->nomehq);
    while(scorri!=NULL)
        {
            if(strcmp(p->nomehq,scorri->nomehq)==0)
                {
                    status=1;
                    printf("Quartiere giC  esistente! Inserire un altro nome \n");
                    return;
                }
            else status=0;
            scorri=scorri->next;
        }
        if(status==0)
            {
                if(*list==NULL)
                    {
                        *list=p;
                    }
                else
                    {
                        for(g=*list;g!=NULL&&strcmp(g->nomehq,p->nomehq)<0;t=g,g=g->next);
                        if(t==g)
                            {
                                p->next=*list;
                                *list=p;
                            }
                        else
                            {
                                t->next=p;
                                p->next=g;
                            }
                    }
            }
}

void inscoda(struct quartiere **list)
{
    char namehq[20];
    int status=0;
    struct quartiere *scorri=*list;
    printf("Inserire nome quartiere: ");
    scanf("%s",namehq);
    while(scorri!=NULL)
    {
        if(strcmp(scorri->nomehq,namehq)==0)
            {
                printf("Quartiere trovato \n");
               status=1;
               struct intervento *p;
               p=(struct intervento*)malloc(sizeof(struct intervento));
               p->next=NULL;
               printf("Inserisci Cognome: ");
               scanf("%s",p->cognome);
               printf("Inserisci Nome: ");
               scanf("%s",p->nome);
               printf("Inserisci Via: ");
               scanf("%s",p->via);
               printf("Inserisci Telefono: ");
               scanf("%s",p->telefono);
               printf("Inserisci Tipo intervento [0=install|1=Esecuzione|2=Test] : ");
               scanf("%d",&(p->t));
               while(getchar()!='\n');
               printf("Inserisci descrizione intervento: ");
               fgets(p->info,31,stdin);
               if(scorri->act==NULL)
                {
                    scorri->act=p;
                    return;
                }
               else
                {
                    struct intervento *scorri1=scorri->act;
                    //while(scorri1->next!=NULL)scorri1=scorri1->next;
                    scorri1->next=p;
                }
            }
        else status=0;
        scorri=scorri->next;
    }
    if(status==0)inshq(list);

}


void stampa(struct quartiere **list)
{
    struct quartiere *scorri=*list;
    while(scorri!=NULL)
        {
            printf("Nome quartiere: %s \n",scorri->nomehq);
            struct intervento *scorri1=(*list)->act;
            while(scorri1!=NULL)
                {
                    printf("Cognome:%s \n",scorri1->cognome);
                    scorri1=scorri1->next;
                }
            scorri=scorri->next;
        }
}
void cont(struct quartiere **list,char nhq[30])
{
    struct quartiere *scorri=*list;
    int i=0,stat=0;
    while(scorri!=NULL)
        {
            if(strcmp(nhq,scorri->nomehq)==0)
                {
                    struct intervento* scorri1=scorri->act;
                    while(scorri1!=NULL)
                        {
                            i++;
                            scorri1=scorri1->next;
                        }
                        printf("Numero interventi quartiere: %s \n Interventi n. %d",scorri->nomehq,i);
                        return;
                }
            scorri=scorri->next;
        }
        printf("non sono stati trovati quartieri con quel nome! \n");
}
void cerca(struct quartiere **list,char nhq[20])
{
    struct quartiere *scorri=*list;
    while(scorri!=NULL)
        {
            if(strcmp(scorri->nomehq,nhq)==0)
                {
                    struct intervento *p;
                    p=scorri->act;
                    scorri->act=scorri->act->next;
                    printf("Cognome del primo in coda: %s \n",p->cognome);
                    printf("Nome del primo in coda: %s \n",p->nome);
                    free(p);
                }
            scorri=scorri->next;
        }
}
int main()
{
    struct quartiere *lista;
    lista=NULL;
    int i=0;
    inshq(&lista);
    while(i<1){
    inscoda(&lista);
    i++;
    }
    cont(&lista,"tremestieri");
    cerca(&lista,"tremestieri");
    //stampa(&lista);
}
Il problema sorge sul sistema operativo utilizzato, se eseguito con il compilatore di linux(gcc) parte senza dare troppi problemi.
Mentre se eseguo lo stesso codice su windows, questo al termine dell'inserimento dei primi dati nella sottolista, fa return e termina il programma :

Codice:

Process returned -1073741819 (0xC0000005)   execution time : 21.037 s
Press any key to continue.

Ora, volendo..il docente utilizza esclusivamente linux, quindi ironicamente non sarebbe un problema , ma a me da fastidio lasciarlo così, vorrei capire quindi cosa fa infuriare windows con il proprio compilatore, qualcuno sa dirmi perchè?

Grazie in anticipo.
vicko98 è offline   Rispondi citando il messaggio o parte di esso
Old 20-08-2018, 15:45   #2
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Nel main() hai scritto:

Codice:
    struct quartiere *lista;
    lista=NULL;
    int i=0;
    inshq(&lista);
vai quindi a dereferenziare lista, che e' un puntatore a NULL. Il risultato non e' predicibile. Probabilmente il compilatore su linux cerca di dare senso a quell'operazione, mentre quello di Windows ti stoppa subito.
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 20-08-2018, 16:20   #3
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da Bellaz89 Guarda i messaggi
Ma sei sicuro? A me questo sembra corretto, perche' alla fine nella funzione inshq non viene passato il puntatore ma la sua reference.
Ops, hai ragione. Sono stato troppo precipitoso.
Cmq se posso permettermi un consiglio: @vicko98, aggiungi sempre il controllo che la malloc() sia andata a buon fine. In caso contrario avrai dei crash senza spiegazione alcuna nel caso la malloc() fallisca
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 20-08-2018, 16:44   #4
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Ok, vediamo se prendo un'altra cantonata. @Bellaz89 correggimi se sbaglio ancora.

Nella
void inshq(struct quartiere** list)

si va a fare
Codice:
    p=(struct quartiere*)malloc(sizeof(struct quartiere));
    p->next=NULL;
Poi si scandisce la lista per inserire p nel caso il quartiere inserito non sia gia' presente.
Prima nota: nel caso il quartiere sia gia' presente ci sara' un memory leak!!!

La cosa interessante e' che il puntatore p->act non e' inizializzato, quindi punta a casaccio.
L'inserimento in inshq() andra' correttamente, mentre l'esecuzione fallira' quindi con un errore in inscoda():

Codice:
               if(scorri->act==NULL)
                {
                    scorri->act=p;
                    return;
                }
               else
                {
                    struct intervento *scorri1=scorri->act;
                    //while(scorri1->next!=NULL)scorri1=scorri1->next;
// SOTTOVENTO - qui
                    scorri1->next=p;
                }
Probabilmente vicko98 ha utilizzato Visual C++ per eseguire questo codice. In modalita' debug, Visual C++ inizializza i dangling pointer a 0xcdcdcdcd in modo che il debugger possa trovare il pattern e andare in crash immediatamente. Questo spiegherebbe la differenza di funzionamento sui due sistemi in oggetto.
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 21-08-2018, 19:39   #5
vicko98
Junior Member
 
Iscritto dal: Aug 2018
Messaggi: 4
Rieccomi,

Scusate se non ho risposto precedentemente, alla fine ho risolto il problema.


Codice:
//p->act=(struct intervento*)malloc(sizeof(struct intervento));
//p->act->next=NULL;
Era necessario definire che p->act fosse null, perchè la sottolista deve essere dichiarata vuota quando si crea un nuovo nodo, dunque ho risolto facendo :

Codice:
p->act=NULL;
(p->act->next=NULL effettivamente non aveva più senso)

Ho trovato la soluzione, ma non ho capito il motivo per cui linux riconosce comunque il puntatore, utilizzandone lo spazio offerto con la malloc..mentre windows riconosce qualche errore e termina li il programma, chissà...

Grazie per il vostro aiuto
vicko98 è offline   Rispondi citando il messaggio o parte di esso
Old 21-08-2018, 21:43   #6
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da vicko98 Guarda i messaggi

Ho trovato la soluzione, ma non ho capito il motivo per cui linux riconosce comunque il puntatore, utilizzandone lo spazio offerto con la malloc..mentre windows riconosce qualche errore e termina li il programma, chissà...

Grazie per il vostro aiuto
Come ti dicevo, e' perche' non avendolo inizializzato avevi un dangling pointer.
In questo senso, Visual Studio e' piu' furbo: quando compili in modalita' debug, inizializza i dangling pointer a 0xcdcdcdcd e questo gli permette di trovare il problema subito e di visualizzartelo con un crash.
Il debugger di linux era decisamente meno furbo e per tua sfortuna il dangling pointer puntava ad una locazione valida. Quindi c'era l'errore anche su linux ma siccome puntava ad una locazione valida (anche se a caso) il software sembrava comunque funzionare
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 22-08-2018, 14:18   #7
fano
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2095
+1 per Windows insomma.

Stresso anch'io questa cosa comunque: testa sempre i valori di ritorno delle funzioni! Su Linux malloc() in realtà non fallisce mai anche se chiedi più della memoria che il sistema realmente può darti (è un "bug" nascosto sotto lo strano nome di "optimistic memory allocation strategy"), altri OS fatti meglio tornano NULL in quei casi, quindi occhio!
__________________
Cosmos C# Open Source Managed Operating System
Cosmos Thread Ufficiale
Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat!
fano è offline   Rispondi citando il messaggio o parte di esso
Old 22-08-2018, 17:09   #8
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12966
Quote:
Originariamente inviato da fano Guarda i messaggi
+1 per Windows insomma.
Al massimo per il compilatore/linker .

Evidentemente VS in modalità debug sostituisce le routine di allocazione per l'heap con routine che inizializzano ad un valore noto.

Dovrebbe essere possibile fare la stessa cosa sotto Linux definendo la variabile d'ambiente: MALLOC_PERTURB_ ad un valore intero. Il suo negato viene usato per riempire la memoria allocata proprio per beccare situazioni strane.

http://man7.org/linux/man-pages/man3/mallopt.3.html

Quote:
Originariamente inviato da fano Guarda i messaggi
Stresso anch'io questa cosa comunque: testa sempre i valori di ritorno delle funzioni! Su Linux malloc() in realtà non fallisce mai anche se chiedi più della memoria che il sistema realmente può darti (è un "bug" nascosto sotto lo strano nome di "optimistic memory allocation strategy"), altri OS fatti meglio tornano NULL in quei casi, quindi occhio!
Premesso che bisogna controllare il valore di ritorno di malloc() a prescindere, la tua considerazione non c'entra niente con l'errore che ha riscontrato l'utente.

Nel suo caso infatti trattasi di memoria allocata correttamente ma non completamente inizializzata, in questo caso c'entra più che altro l'implementazione della malloc() della libreria C, che adotta un pool di memoria da riutilizzare per velocizzare l'allocazione. In questi casi è molto probabile che nella serie di malloc() free() malloc() ti venga riassegnata la stessa memoria.

Quando il sistema operativo (Linux) ti assegna una nuova pagina di memoria infatti questa viene sempre azzerata .

PS: sotto Linux con un compilatore abbastanza recente (gcc) se passi i flag "-Wall -Wextra" è molto probabile che ti dia dei warning sul fatto che utilizzi una variabile non inizializzata.

In ogni caso sempre sotto Linux è possibile utilizzare valgrind, che è una cosa che consiglio sempre quando ci sono problemi di questo tipo.

Cmq quello che bisogna stressare è compilare soprattutto con i warning abilitati: ho visto persone, anche esperte non farlo e per me è da bocciatura .

Ultima modifica di WarDuck : 22-08-2018 alle 17:12.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 22-08-2018, 19:35   #9
melko
Member
 
L'Avatar di melko
 
Iscritto dal: Feb 2011
Messaggi: 46
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Al massimo per il compilatore/linker .
PS: sotto Linux con un compilatore abbastanza recente (gcc) se passi i flag "-Wall -Wextra" è molto probabile che ti dia dei warning sul fatto che utilizzi una variabile non inizializzata.

In ogni caso sempre sotto Linux è possibile utilizzare valgrind, che è una cosa che consiglio sempre quando ci sono problemi di questo tipo.

Cmq quello che bisogna stressare è compilare soprattutto con i warning abilitati: ho visto persone, anche esperte non farlo e per me è da bocciatura .
concordo,
in questo caso però anche con -Wall -Wextra sia gcc che clang non danno warning sulla mancata inizializzazione,
una passata di valgrind invece lo evidenzia subito
melko è offline   Rispondi citando il messaggio o parte di esso
Old 23-08-2018, 12:55   #10
fano
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2095
Anch'io un tempo abilitavo sempre -Wall -Wextra, ma ho notato un "difetto" (va beh oltre all'ovvio che "all" non abilita realmente tutto, ma ci sia "extra" pure) a volte segnala come warning complete sciocchezze e così ti perdi magari quelli "buoni" che - secondo me - in un linguaggio di programmazione serio sarebbero errori belli e buoni.

Ve ne racconto uno che è capitato ad un programmatore junior con monitor di recupero con pure "cluster" bruciati, dopo un merge di 2 branch CVS terrificante fatto alla "linux" (tutto a mano con 2 GVIM affiancati ) tutto compilava e poi andava allegramente in core!
Venivano generati tipo 150 warning quindi venivano tranquillamente ignorati
peccato che dopo circa 6 ore che riguardavamo il diff vediamo una cosa orrida: una sottrazione tra 2 stringhe! Uno dei "-" del diff si era magicamente spostato e "giaceva" su uno dei famosi cluster bruciati.

GCC lo warning lo aveva pure dato, che quella sottrazione tra stringhe non lo convinceva mica, ma poi aveva compilato lo stesso.

Io avevo anche provato a scegliere con cura quali -W abilitare, ma alla fine con ogni versione di GCC cambiano significato... questo è uno dei tanti enormi problemi del C.
__________________
Cosmos C# Open Source Managed Operating System
Cosmos Thread Ufficiale
Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat!
fano è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici DJI Osmo Pocket 4: la gimbal camera tascabile cr...
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori Sony INZONE H6 Air: il primo headset open-back d...
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA Nutanix cambia pelle: dall’iperconvergenza alla ...
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta Recensione Xiaomi Pad 8 Pro: potenza bruta e Hyp...
NZXT H9 Flow RGB+, Kraken Elite 420 e F140X: abbiamo provato il tris d'assi di NZXT NZXT H9 Flow RGB+, Kraken Elite 420 e F140X: abb...
Amazfit Cheetah 2 Pro arriva in Italia: ...
Duolingo ammette l'errore dopo un anno: ...
Samsung Galaxy Tab S10 Lite a 249€: il t...
Samsung Micro RGB: la rivoluzione del co...
Sempre più autonomia per gli smar...
Windows sotto attacco: tre zero-day di M...
Capcom e NVIDIA spiegano il path tracing...
Commissione UE contro Google: Big G dovr...
Pale eoliche che durano 500 anni grazie ...
Blink Mini Pan-Tilt a 19,99€: la telecam...
Google e Gucci collaborano per degli occ...
Adobe e Anthropic insieme: il nuovo Fire...
Netflix, importanti novità per l'...
Top 7 tech più venduti su Amazon ...
Stop alle app pesanti: Android 17 Beta 4...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 13:27.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v