访问/释放动态分配的结构数组时的不需要的行为

时间:2017-04-21 14:52:15

标签: c arrays struct

每次运行时,分段错误都会在GDB中输出。我试图制作一个动态的结构数组。访问/释放数组中的任何内容时出错。

结构:

typedef struct{
  SDL_Texture* texture;
  SDL_Rect textureSelect;
  SDL_Rect objectCollision;//this doesnt have the accuracy of floats, so that might take more work than I want. Use this to get world coordinates
  SDL_Rect objectTransform;
  float objectVelX;
  float objectVelY;
  float objectX;
  float objectY;
  float objectRotation;
  unsigned short hasCollision;
  unsigned short hasPhysics;
  unsigned short used;
  unsigned short visible;
}Object;

罪魁祸首之一:

unsigned short firstCalled = 0;
Object *objects = NULL;
unsigned long objectAmmount = 0;

unsigned long AddObject(SDL_Rect collisionRect, SDL_Rect selectTexture, const char *textureUrl){

  if(firstCalled){//for first time calling

    objects = (Object *)malloc(sizeof(Object));//this is fine

    if(objects == NULL){

      printf("Critical memory allocation error\n");

    } else{
      printf("Allocated memory\n");
    }

  } else{

    Object *tempObjects = (Object *)realloc(objects, (objectAmmount + 2) * sizeof(Object));//have to do 1+ to make room for more

    if(tempObjects == NULL){

      printf("CRITICAL*** Out of memory/memory error\n");

    } else{

      printf("Reallocation successfull\n");

      objects = tempObjects;
      tempObjects = NULL;

    }
  }
//Which then goes on to set each variable to a wanted default value

objects[objectAmmount].textureSelect = selectTexture;
objects[objectAmmount].objectCollision = collisionRect;
objects[objectAmmount].objectTransform.x = 0;
//...

objectAmmount++;



if(firstCalled){//for first time calling
    //just give the function that called this this number because this is the object ID;
    firstCalled = 1;
    return objectAmmount - 1;
  } else{
    return objectAmmount;
  }
}

在渲染功能中:

Object *tempAccessObject = NULL;
void Render(){
  for(i = 0; i <= GetObjectCount(); i++){
    tempAccessObject = GetObject(i);//GetObject returns a pointer to the specific point in the array
    //use the variables in the array to render the objects
   }
}

最后,销毁功能:

void DestroyScene(){
  firstCalled = 0;
  if(objects != NULL){
    printf("Nothing to free\n");
    unsigned long i;
    for(i = 0; i <= objectAmmount; i++){
      if(objects[i].texture != NULL){
        SDL_DestroyTexture(objects[i].texture);
      }
    }
    free(objects);
    objects = NULL;
  }

  objectAmmount = 0;
}

1 个答案:

答案 0 :(得分:0)

它看起来像一个索引问题。以此示例循环:

for(i = 0; i <= objectAmmount; i++){
  if(objects[i].texture != NULL){
    SDL_DestroyTexture(objects[i].texture);
  }
}

该条件表达式应为i < objectAmmount,因为您不想访问objects[objectAmmount],因为它将未被初始化或超出您已分配的内存范围,具体取决于您已经多少次叫AddObject。你malloc只有1个元素,但realloc每次额外加2,这对valgrind等程序来说掩盖了这个问题。

猜测(因为您没有包含GetObjectCount的代码),您的主Render循环也存在此问题。