Bonjour a tous,

Voila deja je vous explique le but de ma fonction, je veux pouvoir "parser" une chaine de caractere pour en extraire les nombres presents.
Chaque chaine (qui corresponds en fait a un "fgets" d'un fichier) est compose, soit :
-de N doubles (N non connu à l'avance)
-d'une serie de caractere alphanumerique sans avoir de nombres apres
-d'un mix des 2.


J'ai donc le code suivant (toutes les securites concernant les codes retour des fonctions etc etc n'y sont pas pour plus de clarté)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
 
#define LINE_BUFFER_SIZE 256 
 
#define xstr(s) str(s)
#define str(s) #s
 
static double * local_realloc(double * pointeur, size_t const oldsize,size_t const newsize)
{
    static const char FCNAME[] = "local_realloc";
    double *val_tmp=pointeur;
 
 
    if (newsize>oldsize)
    {
 
        val_tmp=calloc(newsize,sizeof(*val_tmp));
 
        if (val_tmp==NULL)
        {
            fprintf(stdout,"reallocation error\n");
            return val_tmp;
        }
        else
        {
            size_t indice=0;
            for(indice=0;indice<oldsize;indice++)
                val_tmp[indice]=pointeur[indice];
 
            free(pointeur),pointeur=NULL;
            pointeur=val_tmp;
        }
    }
 
 
    return val_tmp;
}
 
 
double *myfscanline(char const*const  lineToScan, size_t *const NumberValues, size_t *const  TextInLine)
{
 
    static const char FCNAME[] = "myfscanline";
    int rbm_er = 0;
    unsigned int i=0;
    size_t const len = (strlen(lineToScan)>LINE_BUFFER_SIZE?strlen(lineToScan):LINE_BUFFER_SIZE);
    char *tmp=calloc(len,sizeof(*tmp));
    char *buffer_string=calloc(LINE_BUFFER_SIZE+1,sizeof(*buffer_string));
    double *val=calloc(1,sizeof(*val));
    double *val_tmp=NULL;
    char *tmp_dummy=tmp;
    int len_buff=0;
    int len_val=0;
    size_t global_shift=0L;
 
 
    strcpy(tmp,lineToScan);
 
 
    *NumberValues=0;
    *TextInLine=0;
    do
    {
        int res1=0;
        int res=0;
        val[i]=0.;
        *buffer_string='\0';
        len_buff=0;
        len_val=0;
 
        res=sscanf(tmp,"%"xstr(LINE_BUFFER_SIZE)"[a-zA-Z:#;]%n %lf%n ",buffer_string,&len_buff,&val[i],&len_val);
 
        /*si notre chaine contient caractere+nombre */
        if (len_val!=0)
        {
            val_tmp=local_realloc(val,i+1,i+2);
            if (val_tmp==NULL)
            {
                rbm_er = 1;
                free(tmp);
                free(buffer_string);
                free(val);
                return NULL;
 
            }
            val=val_tmp;
            (*NumberValues)++;
            (*TextInLine)++;
            tmp+=(len_val);
 
        }
        else
        {
            /* si on a juste une chaine de caractere */
            if (len_buff!=0)
            {
                tmp+=(len_buff);
                (*TextInLine)++;
                continue;
            }
            else /* buffer vide ou alors juste un chiffre a lire */
            {
                res1=sscanf(tmp," %lf%n ",val+i,&len_val);
                if (len_val!=0)
                {
                    tmp+=len_val;
                    val_tmp=local_realloc(val,i+1,i+2);
                    if (val_tmp==NULL)
                    {
                        rbm_er = 1;
                        free(tmp);
                        free(buffer_string);
                        free(val);
                        return NULL;
 
                    }
 
                    val=val_tmp;
                    (*NumberValues)++;
                }
                else
                {
                    break;
                }
            }
 
        }
 
        i++;
        if ((tmp[0]=='\0')||(tmp[0]=='\n'))
            break;
 
 
        /*reallocation de memoire pour tmp afin de s'assurer qu'il puisse toujours contenir les 256 caracteres */
        global_shift+=(size_t)tmp - (size_t)tmp_dummy;
        tmp=calloc(LINE_BUFFER_SIZE,sizeof(*tmp));
        strcpy(tmp,lineToScan+global_shift);
        free(tmp_dummy);
        tmp_dummy=tmp;
 
 
 
 
    }while(1);
 
    free(tmp_dummy),tmp_dummy=NULL;
    free(buffer_string),buffer_string=NULL;
 
 
    if (rbm_er!=0)
        free(val),val=NULL;
 
    return val;
}

Et j'essaye d'utiliser ma fonction avec une fonction test du type :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
#define B_STRING_1 "1.23\n"
 
int main(void)
{
    char * str_list = calloc(LINE_BUFFER_SIZE,sizeof(*str_list));
 
    int iError = 0;
    double *dVal=NULL;
    size_t iNumVal=0L;
    size_t iText=0L;
    strcpy(str_list,B_STRING_1);
    dVal=myfscanline(str_list,&iNumVal,&iText);
    if (iNumVal!=1)
    {
        iError++;
    }
    else
    {
        if (fabs(dVal[0]-1.23)>=EPS)
        {
            iError++;
        }
    }
 
 
    free(dVal),dVal=NULL;
    free(str_list),str_list=NULL;
    return 0;
}
Le souci est que je me prends un "joli"
***glibc detected *** double free or corruption (out) : 0x089925E0
Sachant que l'adresse 0x089925E0 corresponds à l'adresse de mon tableau 'dVal'

J'ai aussi regarde du cote de valgrind ce qu'il me disait, et il me dit ceci :
==3985== 1 errors in context 1 of 3:
==3985== Invalid free() / delete / delete[]
==3985== at 0x4005B0A: free (vg_replace_malloc.c:325)
==3985== by 0x8053C67: test_io_lib (Bench_lib_files.c:87)
==3985== by 0x804C29B: main (benchmark.c:57)
==3985== Address 0x456be50 is 16 bytes inside a block of size 36 alloc'd (cette adresse corresponds a l'adresse du tableau val dans ma fonction)
==3985== at 0x400677E: malloc (vg_replace_malloc.c:195)
==3985== by 0x80A5687: _mm_malloc (in test_icc_12_.exe)

Je ne doutes pas que mon erreur est stupide et flagrante mais la je seches donc toute aide sera la bienvenue, merci d'avance.


PS : si vous avez besoin d'autres info, je suis dispo.

PS 2 : a la compilation j'ai regarde aussi bien les messages de mon gcc parano que mon icc parano (icc 12) et j'ai meme ressorti lint mais aucune info donnant une piste comme quoi j'utiliserai une variable non initialisée ou autre

Edit : petite precision sur le log valgrind