Правильно ли я создаю экземпляры указателей в моей функции добавления моей реализации кучи в c? - PullRequest
0 голосов
/ 12 марта 2019

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

заголовочный файл heap.h:

struct Entry {
  int key;
  char* value;
};

typedef struct Entry Entry;

struct Heap {
  int capacity;
  int size;
  Entry** elements;
};

typedef struct Heap Heap;

heap.c:

void add(Heap* h, int priority, char* val) {
  if (h->size >= h->capacity) {
    expandCapacity(h);
  }
  //insert at end of storage array and bubble up
  Entry* toAdd = calloc(1, sizeof(Entry*));
  toAdd->key = priority;
  toAdd->value = calloc(1, sizeof(char*));
  toAdd->value = val;
  h->elements[h->size]=toAdd;
  h->size += 1;
  bubbleUp(h, h->size);
}

bubbleUp и swap были предоставлены функции, все, что мне нужно было сделать, это адаптировать их дляэтот проект и перевести их на c, так что, возможно, возникла проблема с этим, хотя они имеют смысл для меня логически.

void bubbleUp(Heap* h, int index) {
   if(index <= 0) { return; }
   Entry* e = h->elements[index];
   Entry* parent = h->elements[(index-1)/2];
   int comp = strcmp(e->value, parent->value);
   if(comp > 0) {
     swap(h, index, parent->key);
     bubbleUp(h, parent->key);
   }
   else {
     return;
   }
}

void swap(Heap* h, int index1, int index2) {
   Entry* tmp = h->elements[index1];
   h->elements[index1] = h->elements[index2];
   h->elements[index2] = tmp;
}

Ответы [ 2 ]

1 голос
/ 12 марта 2019

В

void add(Heap* h, int priority, char* val) {
    if (h->size >= h->capacity) {
        expandCapacity(h);
    }
    //insert at end of storage array and bubble up
    Entry* toAdd = calloc(1, sizeof(Entry*));
    toAdd->key = priority;
    toAdd->value = calloc(1, sizeof(char*));
    toAdd->value = val;
    h->elements[h->size]=toAdd;
    h->size += 1;
    bubbleUp(h, h->size);
}

вы хотите выделить память для одной структуры Entry, а не для ее указателя, поэтому это сделает работу

Entry* toAdd = calloc(1, sizeof(Entry));

Вам не нужно выделять память для указателя toAdd->value, потому что он уже статически выделен компилятором.

На этом этапе, если вы хотите скопировать указатель, просто удалите эту строку toAdd->value = calloc(1, sizeof(char*)); Вместо этого, если вы хотите скопировать содержимое строки, вы должны использовать strncpy

0 голосов
/ 12 марта 2019

Это утечка памяти. Блок выделяется, а затем сразу теряется. Я бы просто удалил первую строку.

toAdd->value = calloc(1, sizeof(char*));
toAdd->value = val;

Кроме того, вы должны выделить sizeof(Entry) здесь, а не размер указателя.

Entry* toAdd = calloc(1, sizeof(Entry*));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...