Seg Fault происходит из-за изменения переменной - PullRequest
2 голосов
/ 16 марта 2012

В основном у меня есть код, который сохраняет ошибки сегмента.Причина в том, что текущий размер моей структуры данных меняется, и я не знаю как.В функции newMap я устанавливаю размер карты равным 0, затем, как только я установил значения указателей на функции, размер будет совершенно другим.Я не уверен, что я делаю здесь не так.

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;
}

Пример вывода

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

1 Ответ

6 голосов
/ 16 марта 2012

На этой строке:

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

map - это Map*, поэтому вы выделяете размер указателя памяти в куче, не размер Map. Это должно быть либо

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

или

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

Это одна из проблем. Если вы это исправите, но есть и другие ошибки, попробуйте решить их самостоятельно, а если не можете, отредактируйте свой вопрос с дополнительной информацией.

...