[c] errore di segmentazione (core dump creato)

di Anonimizzato13086 il
13 risposte
Buongiorno ragazzi.

Ho scritto il seguente programma :

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char* substring(const char* str, int begin, int len)
{
  if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin+len))
    return 0;

  return strndup(str + begin, len);
}

int five_pos(char s[50])
{

int i,cont,ret;
i=-1;
cont = 0;

while(cont<5)
{
i++;

if(s[i]=='&') {cont++;}

}
}

void spacchetta(const char* stringa)
{
int pos5,stlun;
char ssss[50];
int i=0;
for(i=0;i<50;i++)
{
ssss[i]='z';
}
for(i=0;i<50;i++)
{
char* appo = substring(stringa,i,1);
ssss[i]=*appo;
}
for(i=0;i<50;i++)
{
printf("elem %c\n",ssss[i]);
}
pos5=0;
stlun=0;
pos5 = five_pos(ssss); //posizione quinta &
stlun = strlen(stringa); //lunghezza stringa

int begin1 = 0;
int end1 = 2;
char* comando= substring(stringa,begin1,end1);

int begin2 = 4;
int end2 = 1;
char* nodo = substring(stringa,begin2,end2);

int begin3 = 7;
int end3 = pos5-1;
printf("pos5 %i",pos5);
char* ip = substring(stringa,begin3,end3);

int begin4 = pos5+2;
int end4 = 4;
char* porta = substring(stringa,begin4,end4);

int begin5 = pos5+8;
int end5 = stlun-1;
char* altro = substring(stringa,begin5,end5);

//stampo:
printf("comando    = %s\n", comando);
printf("nodo    = %s\n", nodo);
printf("ip    = %s\n", ip);
printf("porta    = %s\n", porta);
printf("altro    = %s\n", altro);
}

int main()
{
const char* ss= "/J&&P&&192.168.0.1&&5940&&PEZZALI";
spacchetta(ss);
}
quando lo compilo tutto ok.

Al momento dell esecuzione mi restituisce solo:
Errore di segmentazione (core dump creato)

senza dirmi altro.

Quindi non riesco a capire dove sia il problema.

Premetto che le funzioni five_pos e substring funzionano,sono gia state testate.


Come ulteriore info, sto lavorando su ubuntu.

13 Risposte

  • Non serve guardare il codice: e' ovvio!

    Antefatti: linguaggio C, vettori di byte (detti stringhe di caratteri, ma e' fondamentale non dimenticarselo), non grande esperienza di programmazione in C

    Effetto: core dump

    Causa: puntatore e 0 o tentativo di scrivere oltre lo spazio disponibile in un buffer.

    Soluzione: non facile. Per prima cosa devi trovare in quale punto del programma avviene il crash.

    Poi, prendere i provvedimenti opportuni

    Assioma: le funzioni della libreria standard sono state testate da talmente tanto tempo e persone che si puo' escludere a priori che il problema sia li.

    Quello che hai scritto tu, invece, anche se fino addesso sembrava funzionare, deve essere ricontrollato minuziosamente.

    I bug legati al non corretto uso dei puntatori e alla scrittura oltre allo spazio messi a dispoziione da un buffer e' uno dei problemi piu' difficili da identificare.
    Il problema e' legato proprio al fatto che fino ad un certo punto il programma funzionava correttamente, e poi BOOM ... non va piu' un accidente!
  • Inanzitutto posso dire che il problema è nella funzione spacchetta
  • Provo a dirti un fatto che si è verificato,

    a me non è di grande aiuto ma magari puo aiutarci.

    Se dove uso il vettore di char

    metto dimensione 30 quindi char s[30]

    il programma non va in crash ma giustamente la stringo che gli passo è maggiore di 30 e ottengo il seguente output
    comando = /J
    nodo = P
    ip = (null)
    porta = (null)
    altro = (null)

    invece se metto come dimensione quella indicata nel codice sopra, ottengo
    Errore di segmentazione (core dump creato)
  • A me il problema sembra evidente ...

    Questo ciclo
    
    for(i=0;i<50;i++)
    {
        char* appo = substring(stringa,i,1);
        ssss[i]=*appo;
    }
    
    esegue 50 volte la substring di stringa ma stringa non è di 50 caratteri e quando i sarà uguale a 33 restituirà NULL nel puntatore appo. L'istruzione seguente, che usa allegramente il puntatore senza controllare se è valido, causa il seg fault.

    A parte questo, la funzione five_pos dovrebbe restituire un valore (di tipo intero) ma non esiste un return nella funzione stessa ... fai attenzione.
  • Hai ragione, nel cut e paste si era persa una riga.

    La funzione è cosi composta:
    
    int five_pos(char s[40])
    {
    
    int i,cont,ret;
    i=-1;
    cont = 0;
    
    while(cont<5)
    {
    i++;
    
    if(s[i]=='&') {cont++;}
    
    }
    return i;
    }
    
  • Non mi è chiara la tua risposta riguardo al fault.

    Come dovrei procedere?

    Grazie
  • Reedit.

    credo di aver capito cosa intendi, provo e ti faccio sapere
  • Ok, funziona perfettamente.

    Dovevo cambiare quei cicli scrivendoli cosi:

    for(i=0;i<stlun-1;i++)
    {
    char* appo = substring(stringa,i,1);
    ssss=*appo;
    }

    poi avevo commesso anche qualche piccolo errore sull'uso del substring ma quello esula dal sementation fault

    Grazie di tutto
  • Spero tu abbia impostato il valore di stlun dato che nella funzione che hai mostrato non lo fai ...

    In ogni caso, un puntatore va controllato e ti suggerirei sempre di scrivere

    if(appo) ssss=*appo;

    Ovviamente quella for ha poco senso ... potresti usare le funzioni di copia delle stringhe ...
  • Per stlun l'ho impostato cosi:

    stlun = strlen(stringa); //lunghezza stringa
  • Così copi solamente il contenuto della stringa ma non il terminatore. E' questa la tua intenzione?

    In poche parole a cosa ti serve questa for?
  • Si non ho bisogno del terminatore.

    Mi serve per creare un array da poter passare alla funzione five_pos

    probabilmente ci sono altri modi, è il primo che mi è venuto

    ps ho inserito il codice if(appo) ssss=*appo;
    in effetti è comodo
  • Scusa ... ma stai facendo il giro del mondo per ottenere il singolo carattere dalla stringa ...

    Secondo me ti basta scrivere
    
    for(i=0;i<stlun-1;i++)
         ssss[i] = stringa[i];
    
    oppure ancora meglio senza for
    
     strncpy ( ssss, stringa, stlun-1);
    
    ambedue enormemente più semplici, veloci, efficienti.
Devi accedere o registrarti per scrivere nel forum
13 risposte