0

我正在做一个项目,我们的教授给了我们代码,其中包含我们无法更改的变量和原型声明。一个是结构,指向该结构的指针的类型定义为pStudentRecord

typedef struct
{
  char* firstName;
  char* lastName;
  int id;
  float mark;
}* pStudentRecord;

使用指向此类型的指针称为g_ppRecords. 这将是一个指向上述结构的动态指针数组。

这就是我的问题所在。将从文件中读取记录。如果指定的文件名不存在,则创建一个新文件名。g_ppRecords每当用户添加第一条新记录时,我都会初始化指针:

if(!n) //where n = number of records
  g_ppRecords = (pStudentRecord*)  malloc(sizeof(pStudentRecord));

g_ppRecords[n] = (pStudentRecord) malloc(16);

到目前为止,此代码每次运行时都有效,但我不确定如何。pStudentRecord如果我添加更多记录,则将在 中的下一个位置创建一个新指针 ( ) g_ppRecords。据我了解,我还没有为那个新指针分配空间,但每次它工作时都没有任何问题。我可以很好地访问新结构的成员,并且我没有收到堆损坏错误或访问冲突或类似的情况。我的担忧是正确的还是我在怀疑自己?

4

3 回答 3

3

根据您显示的代码,您的担忧是有效的。

这一行:

g_ppRecords = (pStudentRecord*)  malloc(sizeof(pStudentRecord));

只为单个 pStudentRecord. 把它想象成一个pStudentRecord只有一个元素的数组, at g_ppRecords[0]

如果我添加更多记录,那么将在g_ppRecords.

现在的问题是当您执行此处描述的操作时可能会发生什么。添加新指针时会发生什么?除非您使用realloc为 获取更多空间g_ppRecords,否则该数组中没有空间容纳更多指向记录的指针。如果你malloc在第二个元素上有一个新指针,即:

g_ppRecords[1] = (pStudentRecord) malloc(16);

g_ppRecords[1]然后,您正在使用尚未分配的内存。这似乎可行,但这段记忆不属于你。继续添加新指针,最终你的程序会中断。或者你的程序可能会因为你的代码的另一部分完全不相关的东西而中断。

解决方法是您最初应该分配您的数组,以便它可以容纳多个指针,而不仅仅是一个。你怎么能用你的第一malloc行做到这一点?

我应该补充一点,当您为struct使用分配内存时,malloc(16)您会假设您不应该做出的数据结构,特别是struct始终占用 16 个字节。鉴于您的typedef: 直接指向来自 anonymous 的指针struct,您可以将其更改16为更通用的内容,但这与您的问题没有直接关系,您应该向教授询问。

于 2012-09-12T14:51:52.320 回答
1

作为一般规则,尽量避免使用malloc( sizeof( type )),尤其是当类型被类型转换混淆时。在变量上调用 sizeof 会更安全:malloc( sizeof x )。此外,在 C 中,您不应该从 malloc 中转换返回值。换句话说,不是只为一条记录分配空间:

g_ppRecords = (pStudentRecord*)  malloc(sizeof(pStudentRecord));

最好通过以下方式为 n 条记录分配空间:

g_ppRecords = malloc( n * sizeof *g_ppRecords );
于 2012-09-12T18:09:02.830 回答
0
typedef struct
{
  char* firstName;
  char* lastName;
  int id;
  float mark;
}* pStudentRecord;

这是一个匿名结构。这里有点奇怪,但也许可以教你一些东西。这样做来创建一个新的:

pStudentRecord ptr;
ptr = malloc(sizeof(*ptr));

这将自动分配适量的内存。

您仍然遇到问题,因为您需要 malloc 数组来保存指针。为此,请执行以下操作:

pStudentRecord* g_ppRecords = malloc(n * sizeof(pStudentRecord));

然后,您可以像这样使用 g_ppRecords:

pStudentRecord ptr = g_ppRecords[3];

综上所述,我们有我们的自定义分配器:

pStudentRecord* g_ppRecords = malloc(n * sizeof(pStudentRecord));

for (size_t i = 0; i < n; ++i)
{
  pStudentRecord ptr;
  g_ppRecords[i] = malloc(sizeof(*ptr));
}

我在没有编译和测试的情况下编写了所有这些,所以可能会有错误(但这不是我的作业:-))

于 2012-09-12T16:45:30.827 回答