2 votes

Erreur de segmentation car la variable est modifiée

En gros, j'ai du code qui continue à se planter. La raison en est que la taille actuelle de ma structure de données est modifiée et je ne sais pas comment. Dans la fonction newMap, je fixe la taille de la carte à 0, puis une fois que j'ai défini les valeurs des pointeurs de fonction, la taille est complètement différente. Je ne suis pas sûr de ce que je fais de mal ici.

Map.h

#ifndef MAP_H
#define MAP_H

typedef struct MapS Map;

struct MapS{
    void* mapPrivateVars;
    void (*add)(Map*, void*, void*);
    void* (*getValue)(Map*, void*);
    long (*getSize)(Map*);
};

Map* newMap();
#endif

Map.c

    #include "Map.h"
#include <stdlib.h>
#include <stdio.h>

void addKey(Map* map, void* key, void* value);
void* getKey(Map* map, void* key);
long sizeMap(Map* map);

#define INITIAL_KEY_VALUE_ARRAY_SIZE 100

typedef struct{
    void* key;
    void* value;
}KeyValuePair;

typedef struct{
    int size;
    int maxSize;
    KeyValuePair** keyValuePairArray;
}MapPrivate;

Map* newMap(){
    Map* map = malloc(sizeof(map));
    if(map==NULL){
        exit(5);
    }
    map->add = NULL;
    map->getValue = NULL;
    map->getSize = NULL;
    MapPrivate* mapPrivate = malloc(sizeof(MapPrivate));
    if(mapPrivate==NULL){
        exit(6);
    }
    KeyValuePair** kvpa = (KeyValuePair**)malloc(INITIAL_KEY_VALUE_ARRAY_SIZE*sizeof(KeyValuePair*));
    mapPrivate->keyValuePairArray = kvpa;
    if(mapPrivate->keyValuePairArray==NULL){
        exit(7);
    }

    map->mapPrivateVars = (void*)mapPrivate;
    MapPrivate* mpv = (MapPrivate*) map->mapPrivateVars;
    mpv->maxSize = INITIAL_KEY_VALUE_ARRAY_SIZE;
    mpv->size = 0;
    printf("size in constructor after assignment is %d\r\n", mpv->size);
    map->add = addKey;
    map->getValue = getKey;
    map->getSize = sizeMap;

    printf("size in constructor before end is %d\r\n", mpv->size);
    return map;
}

void addKey(Map* map, void* key, void* value){
    MapPrivate* privateVars = (MapPrivate*) map->mapPrivateVars;
    if(privateVars->size == privateVars->maxSize){
        //TODO: realloc with more space
        exit(100);
    }
    KeyValuePair* kvp = malloc(sizeof(KeyValuePair));
    if(kvp==NULL){
        exit(8);
    }
    printf("addKey malloced kvp\r\n");
    kvp->key = key;
    kvp->value = value;
    printf("addKey assigned key and value kvp\r\n");
    printf("size is %d\r\n", privateVars->size);
    privateVars->keyValuePairArray[privateVars->size] = kvp;
    printf("addKey added new kvp to kvparray \r\n");
    privateVars->size++;
    printf("addKey incremented size kvp\r\n");
}

void* getKey(Map* map, void* key){
    MapPrivate* privateVars = (MapPrivate*) map->mapPrivateVars;
    int i;
    for(i = 0; i < privateVars->size;i++){
        if(privateVars->keyValuePairArray[i]->key == key){
            return privateVars->keyValuePairArray[i]->value;
        }
    }
    return NULL;
}

long sizeMap(Map* map){
    MapPrivate* privateVars = (MapPrivate*) map->mapPrivateVars;
    return privateVars->size;
}

MapTest.c

#include "Map.h"
#include <stdio.h>

int main(void){
    Map* map = newMap();
    char* dude = "dude";
    char* awesome = "awesome";
    char* meh = "meh";
    map->add(map, dude, meh);
    map->add(map, awesome, dude);
    map->add(map, meh, awesome);
    return 0;
}

Exemple de sortie

size in constructor after assignment is 0
size in constructor before end is 180657104
addKey malloced kvp
addKey assigned key and value kvp
size is 180657104
Segmentation fault: 11

6voto

Seth Carnegie Points 45196

Sur cette ligne :

Map* map = malloc(sizeof(map));

map est un Map* Vous allouez donc la taille d'un pointeur de mémoire sur le tas, no la taille d'un Map . Il devrait être soit

Map* map = malloc(sizeof(*map));

o

Map* map = malloc(sizeof(Map));

C'est l'un des problèmes. Si vous résolvez ce problème et qu'il y en a d'autres, essayez de les résoudre vous-même, et si vous n'y arrivez pas, modifiez votre question en y ajoutant les informations supplémentaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X