Неправильная инициализация массива Dynami c приводит к ошибкам чтения и записи - PullRequest
1 голос
/ 25 марта 2020

Я пытаюсь создать c массив структур.

typedef struct {
    long int val;
    long int time;
    long int last_used;
} pair;

поэтому у меня в основном есть

pair **fifoVM = (pair **) malloc(sizeof(pair *) * framecount);
pair **fifop1VM = (pair **) malloc(sizeof(pair *) * framecount + 1);
pair **fifop2VM = (pair **) malloc(sizeof(pair *) * framecount + 2);
pair **LRUVM = (pair **) malloc(sizeof(pair *) * framecount);

, и я инициализирую все пары, используя

void init(pair **frames, int size) {
    for (int i = 0; i < size; i++) {
        frames[i] = (pair *) malloc(sizeof(pair));
        frames[i]->val = -1;
        frames[i]->last_used = TIME_VAL;
        frames[i]->time = TIME_VAL++;
    }
}

Но к тому времени я пытаюсь освободить его Я получаю ошибку коррупции от Valgrind.

Сначала я думал, что проблема заключается в использовании pair* в массиве, но он все еще не работает только с pair. Я также подумал, что это может быть pair, выходящий из области видимости при возврате init(), но это также и экземпляр true, потому что он освободит только переменную, содержащую указатель.

Также по какой-то странной причине LRUVM является единственным массивом для обработки sh, хотя он и последний.

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>

//since time.h only has millisecond resolution,
//I need to simulate time
int TIME_VAL = 0;

typedef struct {
    long int val;
    long int time;
    long int last_used;
} pair;

//Allocate the pairs for a given array
void init(pair **frames, int size) {
    //iterate through array
    for (int i = 0; i < size; i++) {
        //allocate memory and assign
        frames[i] = (pair *) malloc(sizeof(pair));
        frames[i]->val = -1;
        frames[i]->last_used = TIME_VAL;
        frames[i]->time = TIME_VAL++;
    }
}

int main(int argc, char **argv) {
    //Command line arguements
    int framecount = atoi(argv[1]);
    int x = atoi(argv[2]);
    int NUM_ACCESSES = atoi(argv[3]);
    int NUM_ITERATIONS = atoi(argv[4]);

    for (int i = 0; i < NUM_ITERATIONS; i++) {

        //Allocate Arrays
        pair **fifoVM = (pair **) malloc(sizeof(pair *) * framecount);
        pair **fifop1VM = (pair **) malloc(sizeof(pair *) * framecount + 1);
        pair **fifop2VM = (pair **) malloc(sizeof(pair *) * framecount + 2);
        pair **LRUVM = (pair **) malloc(sizeof(pair *) * framecount);

        //initialize all of the pairs in the arrays
        init(fifoVM, framecount);
        init(fifop1VM, framecount + 1);
        init(fifop2VM, framecount + 2);
        init(LRUVM, framecount);

        //deallocate arrays
        freeList(fifoVM, framecount);
        freeList(fifop1VM, framecount + 1);
        freeList(fifop2VM, framecount + 2);
        freeList(LRUVM, framecount);
    }
}

void freeList(pair **vm, int framecount) {
    for (int i = 0; i < framecount; i++) {
        free(vm[i]);
    }
    free(vm);
}

1 Ответ

1 голос
/ 25 марта 2020

Некоторые размеры распределения вычисляются неправильно: malloc(sizeof(pair *) * framecount + 1) должно быть:

malloc(sizeof(pair *) * (framecount + 1))

Обратите внимание, что ваша структура данных, кажется, имеет косвенное направление без веской причины. Почему бы не размещать массивы структур вместо массивов указателей для структур, выделяемых индивидуально?

Вот упрощенная версия:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>

//since time.h only has millisecond resolution,
//I need to simulate time
int TIME_VAL = 0;

typedef struct {
    long int val;
    long int time;
    long int last_used;
} pair;

//Allocate the pairs for a given array
void init(pair *frames, int size) {
    for (int i = 0; i < size; i++) {
        frames[i].val = -1;
        frames[i].last_used = TIME_VAL;
        frames[i].time = TIME_VAL++;
    }
}

int main(int argc, char **argv) {
    //Command line arguments
    if (argc < 5) return 1;

    int framecount = atoi(argv[1]);
    int x = atoi(argv[2]);
    int num_accesses = atoi(argv[3]);
    int num_iterations = atoi(argv[4]);

    for (int i = 0; i < num_iterations; i++) {
        //Allocate Arrays
        pair *fifoVM = calloc(sizeof(pair), framecount);
        pair *fifop1VM = calloc(sizeof(pair), framecount + 1);
        pair *fifop2VM = calloc(sizeof(pair), framecount + 2);
        pair *LRUVM = calloc(sizeof(pair), framecount);

        if (fifoVM && fifop1VM && fifop2VM && LRUVM) {
            //initialize all of the pairs in the arrays
            init(fifoVM, framecount);
            init(fifop1VM, framecount + 1);
            init(fifop2VM, framecount + 2);
            init(LRUVM, framecount);

            //...
        }
        //deallocate arrays
        free(fifoVM);
        free(fifop1VM);
        free(fifop2VM);
        free(LRUVM);
    }
}
...