2010-07-06 5 views
2

J'essaie d'obtenir une sous-chaîne pour chaque membre de la structure 'structs', puis d'affecter cette sous-chaîne à un nouveau membre du temp_struct. Le problème que j'ai est de savoir comment libérer la sous-chaîne à chaque itération, pour une raison quelconque, le code s'exécute, cependant valgrind lance un Invalid read of size 1, que je suppose que je lis le bloc de mémoire.libérant la sous-chaîne dans c-loop

Comment libérer la sous-chaîne?

Merci

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

struct st_ex { 
    char product[16]; 
    float price; 
}; 
struct st_temp { 
    char *prod; 
}; 

char *temp = NULL; 

// from stackoverflow 
char* substr(const char* source, size_t start, size_t end) 
{ 
    char* dest = malloc(end - start + 1) ; 
    memcpy(dest, &source[start], end - start) ; 
    dest[end - start] = 0 ; 
    return dest ; 
} 

int main() 
{ 
    struct st_ex structs[] = {{"mp3 player", 2.0f}, {"plasma tv", 20.0f}, 
           {"notebook", 10.0f}, {"smartphone", 49.9f}, 
           {"dvd player", 10.0f}, {"matches", 0.2f }}; 
    struct st_temp **temp_struct; 

    size_t j, i; 
    temp_struct = malloc(sizeof *temp_struct * 6); 
    for (j = 0; j < 6; j++) 
     temp_struct[j] = malloc(sizeof *temp_struct[j]); 

    size_t structs_len = sizeof(structs)/sizeof(struct st_ex); 

    for(i=0; i<structs_len; i++){ 
     temp = substr(structs[i].product, 0, 4); 
     temp_struct[i]->prod = temp; 
     free(temp); 
     temp = NULL; 
    } 
    for(i=0; i<6; i++) 
     printf("%s\n",temp_struct[i]->prod); 

    for(i=0; i<6; i++) 
     free(temp_struct[i]); 

    free(temp_struct); 
    return 0; 
} 
+0

info Grand, merci tout le monde! – Josh75

Répondre

1

1) Vous libérez la sous-chaîne

temp = substr(structs[i].product, 0, 4); 
    temp_struct[i]->prod = temp; 
    free(temp); 

La troisième ligne libère au-dessus de la mémoire que vous malloc'd dans substr. 2) parce que vous libérez la mémoire ici, vous avez introduit un bug.
Il est invalide d'accéder à la mémoire malloc'd après l'avoir libérée, donc il n'est pas valide d'essayer d'imprimer temp_struct[i]->prod.

La solution?
Ne pas free(temp), à la place dans votre boucle pour libérer temp_struct[i], vous devez d'abord libérer temp_struct[i]->prod, comme celui-ci

for(i=0; i<6; i++)  
{ 
    free(temp_struct[i]->prod); 
    free(temp_struct[i]);  
} 
0

Est-ce pas sous-chaînes gratuites. En C, une sous-chaîne fait partie de la chaîne d'origine. Si vous souhaitez obtenir une sous-chaîne indépendante d'une chaîne, utilisez strdup.

+0

Josh est la mémoire malloc'ing pour la sous-chaîne, donc il doit libérer. S'il utilise strdup, où devrait-il libérer la chaîne dup'ed? –

1

Josh, votre temp_struct est tenant à la sous-chaîne ... vous ne voulez pas libérer la sous-chaîne où vous le libérez actuellement. La lecture invalide vient de cette ligne:

for(i=0; i<6; i++) 
    printf("%s\n",temp_struct[i]->prod); 

Au lieu de cela, vous voulez libérer la sous-chaîne lorsque vous libérez votre struct temp, comme ceci:

for(i=0; i<6; i++) 
{ 
    free(temp_struct[i]->prod); 
    free(temp_struct[i]); 
} 
Questions connexes