2017-07-09 5 views
2

J'ai créé ce code pour tester une erreur, que j'obtiens dans mon code principal, et il partage le même problème. Je reçois toujours des erreurs de segmentation ou des données corrompues (zéros ou nombres étranges).Erreur de segmentation après realloc dans la fonction

Voici le code:

int *p=NULL; 
int func (int **point); 

int main() { 
    int num = 5647; 
    p = malloc(sizeof(int)*2); 
    p[0] = num; 
    p[1]= 657; 
    printf("%d\n", p[0]); 
    printf("%d\n", p[1]); 
    func(&p); 
    printf("%d\n", p[0]); 
    printf("%d\n", p[1]); 
    printf("%d\n", p[2]); 
    printf("%d\n", p[3]); 
    return 0; 
} 

int func (int **point){ 
    *point = realloc(*point,sizeof(int)*4); 
    if (*point==NULL){ 
     printf("\n abort \n"); 
     exit(0); 
    } 
    *point[0] = 867; 
    *point[1]= 777; 
    *point[2] = 67; 
    *point[3]= 77; 
} 

Je reçois la faute de segmentation sur le *point[1]=777;. Si j'essaie de faire comme point[1]=777;, je reçois des données erronées. Avec tous les changements dans int func (int **point); ou func(&p); je reçois défaut de segmentation sur realloc.

S'il vous plaît aviser, j'ai lu des informations sur les doubles pointeurs et essayé de suivre toutes les solutions que j'ai trouvées, mais chaque fois que je reçois cette erreur.

Répondre

8

Votre problème concerne la priorité de l'opérateur, remplacez *point[0] par (*point)[0] et ainsi de suite.

Ce que vous avez en ce moment c'est *(point[0]). Vous traitez un pointeur vers un seul élément comme un pointeur vers plusieurs éléments consécutifs, puis déréférencer une valeur indéterminée en tant qu'adresse. Cela se traduit par un comportement indéfini, qui heureusement pour vous se manifeste comme un accident.

Après la modification, vous déréférence d'abordpoint puis utilisez cette adresse pour indexer dans les éléments consécutifs que vous avez alloués.

Deux suggestions d'amélioration:

Ne pas affecter le résultat de realloc directement à *point. Si l'appel échoue, vous perdez la mémoire d'origine. Attribuez-le à une première temporaire pour vérification.

Essayez également de ne pas répéter les types. Au lieu de sizeof(int), essayez pour sizeof(**point), c'est-à-dire quel que soit le buffer de sortie supposé pointer. De cette façon, vous n'aurez pas d'erreurs silencieuses dans votre code si vous changez le type de int en quelque chose d'autre.

void *point_check = realloc(*point,sizeof(**point)*4); 
if (point_check == NULL){ 
    printf("\n abort \n"); 
    exit(0); // If this ever returns instead of exit, `*point` will not leak 
} 
*point = point_check; 
+1

Merci beaucoup! –