【问题标题】:Incrementing pointers to struct增加指向结构的指针
【发布时间】:2013-02-23 19:48:10
【问题描述】:

简单来说,我声明了一个结构体:

typedef struct
{

char* studentID;
char* studentName;
int* studentScores;

}STUDENT;

然后我声明了一个指针并为指针和每个元素分配了内存:

STUDENT* studentPtr = NULL;

   if ((studentPtr = (STUDENT*) calloc (5, sizeof(STUDENT))) == NULL)
{
    printf("Not enough memory\n");
    exit(100);
}

{
    if ((studentPtr->studentID = (char*) calloc (20, sizeof(char))) == NULL)
    {
        printf("Not enough memory\n");
        exit(100);
    }

    if ((studentPtr->studentName = (char*) calloc (21, sizeof(char))) == NULL)
    {
        printf("Not enough memory\n");
        exit(100);
    }
    if ((studentPtr->studentScores = (int*) calloc (5, sizeof(int))) == NULL)
    {
        printf("Not enough memory\n");
        exit(100);
    }

之后,我想从文件中读取 5 条记录,但由于我的增量,当我尝试运行程序时出现错误。 (如果我有类似“char studentName[20];”之类的东西,它工作得很好)我应该如何增加指针以达到我想要的结果?必须是指针符号。

STUDENT* ptr = studentPtr;

while (*count < MAX_SIZE)
{
    fscanf(spData, "%s %*s %*s %*d %*d %*d %*d %*d", ptr->studentName)
    (*count)++;
    ptr++;
}

File Content:

Julie Adams 1234    52  7   100 78  34

Harry Smith 2134    90  36  90  77  30

Tuan Nguyen 3124    100 45  20  90  70

Jorge Gonzales  4532    11  17  81  32  77

Amanda Trapp    5678    20  12  45  78  34

最后一个问题: 如果我保留我声明的结构并为它正确分配内存。完成后如何释放它?应该是这样的吗?

for (STUDENT* ptr = studentPtr; ptr < studentPtr + *count; ptr++)
{   //*count is the number of records
    free(ptr->studentID);
    free(ptr->studentName);
    free(ptr->studentScores);
}
  free(studentPtr);

【问题讨论】:

  • but I get an error - 你得到什么错误? (我很想链接到toomuchcode.org/2008/11/guru-myth.html :-))
  • 抱歉没有具体说明。我在 Xcode 中得到“EXC_BAD_ACCESS (code =1, address = 0 x 0)。我也尝试在其他编译器中运行此代码,但它也失败了。
  • 您可以共享文件中的数据吗?您似乎在格式说明符中缺少“\n”或其他一些字符,请尝试逐一阅读每个条目,您将了解您缺少什么
  • 如果你的字段是固定长度的,为什么在结构中使用数组语法?它会给出相同的最终结果,但使用更少的代码和内存。
  • 为什么count 是一个指针?为什么(*count)++;

标签: c arrays pointers struct increment


【解决方案1】:

问题是您只为 studentPtr[0] 中的字段分配了内存。表中的其余四个条目仍然为零。

试试这个:

int i;
for (i = 0; i < 5; i++)
{
    if ((studentPtr[i]->studentID = (char*) calloc (20, sizeof(char))) == NULL)
    {
        printf("Not enough memory\n");
        exit(100);
    }

    if ((studentPtr[i]->studentName = (char*) calloc (21, sizeof(char))) == NULL)
    {
        printf("Not enough memory\n");
        exit(100);
    }
    if ((studentPtr[i]->studentScores = (int*) calloc (5, sizeof(int))) == NULL)
    {
        printf("Not enough memory\n");
        exit(100);
    }
}

事实上,通过为各个字段使用动态分配的内存,您的生活变得更加艰难。您不仅需要显式分配每个字段(并且可能稍后释放它们),这会花费代码和时间,而且还会在堆表中产生额外的内存开销。如果您的字段是可变大小的,但它们是固定大小的,这将是必要的,因此直接数组更有效。

所以,我最终会这样:

typedef struct
{
  char studentID[20];
  char studentName[21];
  int studentScores[5];
} STUDENT;

STUDENT studentPtr[5];

【讨论】:

  • 噢,我没有意识到我实际上并没有为其他条目分配内存。非常感谢!我真的很感谢你的帮助。看来我仍然需要一些时间来将指针视为数组。是的,我知道我可以简单地设置固定长度,但我需要为 struct 中的每个元素动态分配内存以练习我的内存管理技能。再次非常感谢!
  • 要正确地做到这一点,您应该将每个字符串读入一个大的临时缓冲区,然后 然后 malloc 保存字符串所需的确切内存量,最后复制字符串到新的记忆。
  • 最后一个问题。完成后如何释放结构?编辑了帖子。
  • 哪一个?仅包含数组的结构可以在一次调用中释放。充满 malloc 指针的结构必须单独释放每个 malloc。基本上,您只有一些代码可以对结构中的每个指针执行免费操作。只要确保你没有释放相同的东西两次,并且任何 unallocated 指针始终保留NULL
【解决方案2】:

首先,您将内存分配给结构指针的内存是结构内存的 5 倍。

再次在同一行上,您仅将内存分配给您分配的第一个结构(5 个结构)。

你应该做 5 次,因为你有 5 个结构,例如:

for (i = 0; i < 5; i++)
{
//Do assignments to each element in structure not more than required
//as you are doing in your code:
studentPtr[i]->studentScores = (int*) calloc(5,sizeof(int))
//so your assignment of memory should be:
studentPtr[i]->studentScores = (int*) calloc(sizeof(int))
}

【讨论】:

  • 不要强制转换 calloc() 的结果,这样做是 100% 没有意义的,如果程序是用 C90 编译器编译的,可以隐藏错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
  • 2012-03-28
  • 1970-01-01
相关资源
最近更新 更多