0
votes

Défaut de segmentation lors de l'accès à un pointeur de structure en structure

J'ai un problème avec les pointeurs à la structure qui ont des membres qui sont des pointeurs à la structure aussi.

Parcourir les questions similaires suggérées que j'ai découvert sur ceci: p>

éléments d'accessoires dans un pointeur d'une structure à l'intérieur d'un autre pointeur à un autre pointeur à un autre pointeur à un autre pointeur struct p>

où les gens suggèrent de faire attention à la mémoire d'allocation de la structure. P>

Je pense que cela se fait correctement dans mon code. P>

typedef struct {
  int id_vec;
  float *vec_value;
} Vector;

typedef struct cluster{
  int id_cluster;
  float *centroid;
  Vector *patternInCluster; 
} Cluster;

int main(void){
  Cluster *cluster_ptr= malloc(3 * sizeof(Cluster));
  if (cluster_ptr==NULL){
    printf("NULL");
  }
  cluster_ptr->patternInCluster=malloc(2 * sizeof(Vector *));
  if (cluster_ptr->patternInCluster==NULL){
    printf("NULL");
    cluster_ptr->patternInCluster=NULL;
  }

  float p1[3]={0.0f,1.0f,2.0f};
  Vector *somePattern=malloc(2 * sizeof(Vector));
  somePattern[0].id_vec=1;
  somePattern[0].vec_value=p1;
  somePattern[1].id_vec=2;
  somePattern[1].vec_value=p1;
}


2 commentaires

OT: En ce qui concerne: typlef struct {int ID_VEC; flotteur * vec_value; } Vector; 1) Incluez toujours un nom "Tag" car la plupart des debuggers utilisent le nom "Tag" pour accéder aux champs individuels de la structure. 2) Pour la flexibilité, séparez la définition de la structure d'un typedef pour cette structure


Le code posté ne compile pas! Alors, comment vous attendez-vous à que nous puissions reproduire le problème puis vous aider à le déboguer?


3 Réponses :


1
votes

C'est parce que vous ne remplissez pas les choses complètement.

Cette ligne xxx

est identique à dire xxx

et vraiment donné que cluster_ptr a été attribué sous 3 cluster Il serait plus clair dans votre code pour faire ce dernier.

depuis < Code> Cluster_PTR [1] .pattatnincluster n'a pas reçu de valeur, en essayant de déréférencer, il conduira à un comportement indéfini, mais plus probablement entraînera une défaillance de segmentation.


0 commentaires

1
votes

Vous n'allouez pas assez de mémoire:

cluster_ptr->patternInCluster=malloc(2 * sizeof(Vector));


2 commentaires

Je pense que cela est vrai, mais ne résout pas le problème.


Il y a trop de problèmes pour les résoudre tous à la fois. Étant donné que votre structure est supérieure à 1 pointeur, vous accédez à la mémoire que vous ne possédez pas. Il est toujours difficile d'obtenir tous les problèmes s'il y a plusieurs questions dans une question.



0
votes

Votre problème n'accède pas au pointeur à l'intérieur de la structure. Votre problème est de savoir comment vous utilisez malloc () code>.

Lorsque vous avez un pointeur, vous n'avez qu'une seule fois: p>

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

typedef struct {
    int id_vec;
    float *vec_value;
} Vector;

typedef struct cluster{
    int id_cluster;
    float *centroid;
    Vector **patternInCluster;
} Cluster;

int main(void){

    Cluster **cluster_ptr = (Cluster **)malloc(sizeof(Cluster*));
    for (long unsigned int i = 0; i < 3; i++) {
        cluster_ptr[i] = (Cluster *)malloc(sizeof(Cluster));
        if (cluster_ptr[i]==NULL){
            printf("NULL");
        }

        cluster_ptr[i]->patternInCluster = (Vector **) malloc(sizeof(Vector*));
        for (long unsigned int j = 0; j < 3; j++) {
            (*cluster_ptr)->patternInCluster[j] = (Vector *) malloc(sizeof(Vector));
            if ((*cluster_ptr)->patternInCluster[j]==NULL){
                printf("NULL");
                (*cluster_ptr)->patternInCluster[j]=NULL;
            }
        }
    }



    float p1[3]={0.0f,1.0f,2.0f};
    Vector *somePattern= (Vector *) malloc(sizeof(Vector));
    somePattern[0].id_vec=1;
    somePattern[0].vec_value=p1;
    somePattern[1].id_vec=2;
    somePattern[1].vec_value=p1;

    cluster_ptr[1]->patternInCluster[1] = &somePattern[0];
    cluster_ptr[0]->patternInCluster[1] = &somePattern[1];
    cluster_ptr[1]->patternInCluster[0] = &somePattern[1];
    cluster_ptr[2]->patternInCluster[1] = &somePattern[0];

    printf("%d\n", cluster_ptr[1]->patternInCluster[1]->id_vec);
    printf("%d\n", cluster_ptr[0]->patternInCluster[1]->id_vec);
    printf("%d\n", cluster_ptr[1]->patternInCluster[0]->id_vec);
    printf("%d\n", cluster_ptr[2]->patternInCluster[1]->id_vec);

    return 0;
}


3 commentaires

Merci beaucoup pour la belle explication. Dans le code, vous déclarez cluster_ptrs a ** cluster mais cela semble bizarre pour moi, car je veux qu'il indique un "vecteur" de la structure. Comme vous l'avez dit, j'ai mal compris que Cluster * Cluster_PTR = MALLOC (3 * Tailleof (Cluster)) Allouez suffisamment de mémoire pour 3 pointer sur STRIT, tandis que cela ne donne que cet espace à Cluster_PTR [0 ]. Alors pourquoi changer le type de cluster * `` `` to cluster ** Quand je peux simplement allouer la mémoire pour chaque * cluster_ptr [i] .pattatnincluster dans une boucle?


@LUCAJUNGLA, vous pouvez essayer de supprimer le ** à partir du pointeur Cluster , puis remplacez tout . avec -> -> puis exécutez le programme et voyez s'il produit la bonne sortie. (Astuce: ce n'est pas le cas.)


Ce n'est pas ce que je veux dire pour (i = 0; i alors toute cette affectation: < code> cluster_ptr [0] .pattatnincluster [0] = ONPATTERN [0]; cluster_ptr [1] .patternincluster [0] = OnePattern [1]; etc ... fonctionne et imprimez la bonne valeur