【问题标题】:free causing seg fault on allocated array of structs免费导致分配的结构数组上的段错误
【发布时间】:2015-11-05 02:55:23
【问题描述】:

我想我似乎在为数组中的每个结构分配空间(查看数组中每个结构的第一个元素的地址)

我显然不明白 C 是如何分配东西的... 使用 valgrind 我看到类似

==9852== Use of uninitialised value of size 8
==9852==    at 0x400740: main (Test.c:24)

我对此感到困惑。我看过很多关于数组、结构和分配的帖子,但似乎看不出其中的微妙之处。

我还发现令人费解的是,除了免费之外,一切正常,例如,打印数组值显示了预期的结果。当分配给未分配的(NULL)内存或超出分配的大小(可能)时,我可以理解一个段错误,但不明白 free 发生了什么

// Vector3.h

#include <stdio.h>

typedef struct {
   double    x,y,z;
} Vector3;

void Vector3Print(Vector3 v);


// Vector3.c

#include "Vector3.h"

void Vector3Print(Vector3 v) {
  printf("%f, %f, %f\n", v.x, v.y, v.z);
}


// Mesh.h

#include "Vector3.h"

typedef struct {
   Vector3  position;
   Vector3  rotation;
   Vector3* Vertices;
} Mesh;

void MeshAllocate( Mesh mesh, int size);
void MeshRelease( Mesh mesh);


// Mesh.c

#include <stdlib.h>
#include "Mesh.h"

void MeshAllocate( Mesh mesh, int size) {  // size in verts
  mesh.Vertices = malloc(size * sizeof(Vector3));
  if (mesh.Vertices==NULL) {
    printf("Error allocating memory!\n");
  }
}

void MeshRelease( Mesh mesh) {
  free(mesh.Vertices);
}


// test.c

// gcc -g -std=c99 *.c -o test

#include "Mesh.h"

int main () {

  Mesh mesh;

  printf("sizeof double %lu\n",sizeof(double));
  printf("sizeof Vector3 %lu\n",sizeof(Vector3));

  MeshAllocate(mesh,3);

  printf("address v0.x %lu\n",(unsigned long)&mesh.Vertices[0].x);
  printf("address v0.y %lu\n",(unsigned long)&mesh.Vertices[0].y);
  printf("address v0.z %lu\n",(unsigned long)&mesh.Vertices[0].z);
  printf("address v1.x %lu\n",(unsigned long)&mesh.Vertices[1].x);

  mesh.Vertices[0] = (Vector3){0.1,2.3,4.5};
  mesh.Vertices[1] = (Vector3){6.7,8.9,10.11};
  mesh.Vertices[2] = (Vector3){12.13,14.15,16.17};

  for (int i=0; i<3; i++ ) {
    Vector3Print(mesh.Vertices[i]);
  }

  MeshRelease(mesh);
}

【问题讨论】:

  • 你有内存溢出和损坏。 free 只是检测到这一点。

标签: c arrays memory-management struct free


【解决方案1】:

您的分配和释放对我来说看起来不错,问题是您通过值而不是通过引用传递 Mesh 对象,这意味着在 MeshRelease 和 MeshAllocate 的范围内,您正在处理网。当您进入 MeshRelease 时,您正在尝试释放未分配的内存,因为该上下文中的“网格”对象从未分配过内存(它与 MeshAllocate 操作的网格不同)。

您可以通过将 Mesh 的地址传递给这两个函数来修复它。

test.c

#include "Mesh.h"

int main () {

  Mesh mesh;

  printf("sizeof double %lu\n",sizeof(double));
  printf("sizeof Vector3 %lu\n",sizeof(Vector3));

  MeshAllocate(&mesh,3);

  printf("address v0.x %lu\n",(unsigned long)&mesh.Vertices[0].x);
  printf("address v0.y %lu\n",(unsigned long)&mesh.Vertices[0].y);
  printf("address v0.z %lu\n",(unsigned long)&mesh.Vertices[0].z);
  printf("address v1.x %lu\n",(unsigned long)&mesh.Vertices[1].x);

  mesh.Vertices[0] = (Vector3){0.1,2.3,4.5};
  mesh.Vertices[1] = (Vector3){6.7,8.9,10.11};
  mesh.Vertices[2] = (Vector3){12.13,14.15,16.17};

  for (int i=0; i<3; i++ ) {
    Vector3Print(mesh.Vertices[i]);
  }

  MeshRelease(&mesh);
}

Mesh.c

#include <stdlib.h>
#include "Mesh.h"

void MeshAllocate( Mesh* mesh, int size) {  // size in verts
  mesh->Vertices = malloc(size * sizeof(Vector3));
  if (mesh->Vertices==NULL) {
    printf("Error allocating memory!\n");
  }
}

void MeshRelease( Mesh* mesh) {
  free(mesh->Vertices);
}

Mesh.h

#include "Vector3.h"

typedef struct {
   Vector3  position;
   Vector3  rotation;
   Vector3* Vertices;
} Mesh;

void MeshAllocate( Mesh* mesh, int size);
void MeshRelease( Mesh* mesh);

【讨论】:

    【解决方案2】:
    void MeshAllocate( Mesh mesh, int size) {  // size in verts
      mesh.Vertices = malloc(size * sizeof(Vector3));
      if (mesh.Vertices==NULL) {
        printf("Error allocating memory!\n");
      }
    }
    

    您的错误在此函数中。

    您的代码似乎可以在 free() 下运行,因为您很幸运。

    【讨论】:

    • 实际上并没有回答问题
    • @ChrisCamacho 我想提供帮助,但不是为你做功课。
    猜你喜欢
    • 2014-12-27
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多