简体   繁体   English

指向结构值 Memory 泄漏的指针

[英]Pointer to Struct Value Memory Leak

I am designing an ECS and I have a struct that holds two values: an array of integers and a double pointer.我正在设计一个 ECS,我有一个包含两个值的结构:一个整数数组和一个双指针。 I also have another structure that holds a pointer to the previous struct.我还有另一个结构,它包含指向前一个结构的指针。

I'm able to access to the pointer to the first struct.我可以访问指向第一个结构的指针。 However, whenever I try to access any of the pointers in the struct, I end up having a memory leak.但是,每当我尝试访问结构中的任何指针时,我最终都会遇到 memory 泄漏。

Simple Implementation:简单实现:

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

#define MAX_ENTITIES 4096
#define MAX_COMPONENTS 16

typedef unsigned int Entity;
typedef struct ENTITYMANAGER {
  Queue* available;
  unsigned int count;
} ENTITYMANAGER;

typedef void* Component;
typedef struct COMPONENTMANAGER {
  unsigned int* count;
  Component** available;
} COMPONENTMANAGER;

typedef struct COORDINATOR {
  ENTITYMANAGER* entities;
  COMPONENTMANAGER* components;
} COORDINATOR;

typedef struct Test {
  int num;
  char* string;
} Test;

Test* createTestComponent(char* string, int number) {
  Test* test = (Test*) malloc(sizeof(Test));
  test -> num = number;
  test -> string = (string) ? string : "Test Component";
  return test;
}

static ENTITYMANAGER* createEntityManager(void) {
  ENTITYMANAGER* entities = (ENTITYMANAGER*) malloc(sizeof(ENTITYMANAGER));
  entities -> available = queue(MAX_ENTITIES);
  entities -> count = 0;
  return entities;
}

static COMPONENTMANAGER* createComponentManager(void) {
  COMPONENTMANAGER* components = (COMPONENTMANAGER*) malloc(sizeof(COMPONENTMANAGER));
  components -> available = (Component**) malloc(sizeof(Component*) * MAX_ENTITIES);
  for (int element = 0; element < MAX_ENTITIES; element++)
    (components -> available)[element] = (Component*) calloc(MAX_COMPONENTS, sizeof(Component));

  components -> count = (int*) calloc(MAX_ENTITIES, sizeof(int));
  return components;
}

COORDINATOR* init(void) {
  COORDINATOR* coordinator = (COORDINATOR*) malloc(sizeof(COORDINATOR));
  coordinator -> entities = createEntityManager();
  coordinator -> components = createComponentManager();
  return coordinator;
}

Entity createEntity(COORDINATOR* coordinator) {
  if (!(coordinator && (coordinator -> entities -> count < MAX_ENTITIES)))
    return NULL_ITEM;

  Entity entity = front(coordinator -> entities -> available);
    dequeue(coordinator -> entities -> available);
    (coordinator -> entities -> count)++;

  return entity;
}

void createComponent(COORDINATOR* coordinator, Entity entity, int cnum, void* data) {
  if (!coordinator)
    return;

  (coordinator -> components -> available)[entity][cnum] = createTestComponent(data, 5);
  (coordinator -> components -> count)[entity]++;
}

int main(int argc, char const *argv[]) {
  COORDINATOR* coordinator = init();

  Entity test = createEntity(coordinator);
  createComponent(coordinator, test, 0, NULL);

  Test* component = (Test*) (coordinator -> components -> available)[test][0];
  printf("Test Component: (\"%s\", %d)", component -> string, component -> num);

  return 0;
}

Queue Implementation: Queue.h队列实现: Queue.h

Solution : I had to update my ENTITYMANAGER creation method, which was causing my Entity creation returning an out of bound value causing the memory leak.解决方案:我必须更新我的ENTITYMANAGER创建方法,这导致我的Entity创建返回一个超出界限的值,从而导致 memory 泄漏。 Specifically, I filled the queue which stores the available entity values with valid values.具体来说,我用有效值填充了存储可用实体值的队列。

static ENTITYMANAGER* createEntityManager(void) {
  ENTITYMANAGER* entities = (ENTITYMANAGER*) malloc(sizeof(ENTITYMANAGER));
  entities -> available = queue(MAX_ENTITIES); entities -> count = 0;
  for (Entity entity = 0; entity < MAX_ENTITIES; entity++)
    enqueue(entities -> available, entity);

  return entities;
}

That's quite a mouthful, and difficult to understand.说的有点啰嗦,也很难理解。

Since it appears that you want an unchanging 'hierarchy' of nested structs, simply declare them that way...由于您似乎想要嵌套结构的不变“层次结构”,因此只需以这种方式声明它们......

typedef struct {
    int countused;
    int elements[ 128 ];
} Bits_t;

typedef struct {
    int countused;
    Bits_t bits[ 32 ];
} DiffBits_t;

typedef struct {
    int countused;
    DiffBits_t random[ 16 ];
} Outter_t;

void main( void ) {
    Outter_t *topLevel = malloc( sizeof(*topLevel) );

    printf( "%d", sizeof(Outter_t) );

    topLevel->countused = 1;
    topLevel->random[4].countused = 1;
    /* or */
    DiffBits_t *tmp = &topLevel->random[4];
    tmp->countused = 1;
}

Further, use calloc() instead of malloc() and you won't have to zero-out the nested arrays...此外,使用calloc()而不是malloc()并且您不必将嵌套的 arrays...

I suppose there's no memory issue for above code.我想上面的代码没有 memory 问题。

I'm just confused you even are not able to access coordinator -> components -> count)[0] .我只是对您甚至无法访问coordinator -> components -> count)[0]感到困惑。 It looks like type of Component is a pointer from (components -> available)[itr][stp] = NULL;看起来 Component 的类型是来自(components -> available)[itr][stp] = NULL; . . If it's not initialized definitely there will be an error to access it.如果它没有被初始化肯定会有一个错误访问它。 But there should be no issue to access (coordinator -> components -> count)[0] .但是访问(coordinator -> components -> count)[0]应该没有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM