带循环的结构和内存分配
Struct and memory allocation with loop
我一直在尝试 free() 最后的内存,但是我的导师说我已经创建了 3 个 malloc 指针(使用当前设置)。
注意:关于 malloc/what 在内存中实际发生的事情,我想要尽可能详细的解释。
如果能指导我如何确保没有内存泄漏,我将不胜感激。
下面是我写的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LUNCH_ITEMS 5
#define REMAINING 2
#define CHAR_SIZE 256
int main(void)
{
struct Food
{
char *name; //name attribute of food
int weight, calories;
} lunch[LUNCH_ITEMS] = {{"apple", 4, 100}, {"salad", 2, 80},};
int loopCount;
//INPUT
char *namePtr = NULL;
for (loopCount = REMAINING; loopCount < LUNCH_ITEMS; ++loopCount)
{
char tempBuffer[CHAR_SIZE];
printf("Enter name of item,the weight of item, and the calories in that item: \n");
// store name string in a tempBuffer. weight and calories directly into lunch structure array address
scanf("%255s %d %d", tempBuffer, &lunch[loopCount].weight, &lunch[loopCount].calories);
// get the exact size of (memory of) the input string including add one for null char
size_t exactMemory = strlen(tempBuffer) + 1;
//dynamically allocate the exact amount of memory determined in the previous step
namePtr = (char *)malloc(exactMemory * sizeof(char));
// check if no memory is allocated for foodPtr
if (namePtr == NULL)
{
fprintf(stderr, "Not enough memory available***\n Terminating Program");
exit(1);
}
//store the pointer to it in the name member of the structure in
//the current lunch array element.
(lunch + loopCount)->name = namePtr;
// Copy the food name (stored in tempbuffer) into the dynamically-allocated
// memory using the memcpy function
memcpy(namePtr, tempBuffer, exactMemory);
//(lunch + loopCount)->name = namePtr;
}
//DISPLAY
printf("Item Weight Cals\n---------------------------------------------\n");
for (loopCount = 0; loopCount < LUNCH_ITEMS; loopCount++)
{
int weight = lunch[loopCount].weight;
int cals = lunch[loopCount].calories;
printf("%-12.20s%22d%11d\n", (lunch + loopCount)->name, weight, cals);
if (loopCount > REMAINING)
{
//(lunch+loopCount)->name = NULL;
namePtr = NULL;
free(namePtr);
//free((lunch + loopCount)->name);
}
}
//De-allocate all malloc'd memory
return EXIT_SUCCESS;
}
我的输出-
Item Weight Cals
-----------------
apple 4 100
salad 2 80
hello 22 33
maybe 44 45
right 100 200
我认为您的讲师关于 3 个 malloc'ed 字符串的评论是一个非常有力的线索。我注意到您有一个包含 5 个项目的数组,其中预填充了 2 个项目。 5 - 2 是 3.
此外,请注意 C 中的索引从 0 开始。您预先初始化数组的 2 个项目将具有索引 0 和索引 1。索引 2 将是第一个输入的数据。使用 > 2 比较该索引实际上会导致您跳过用户提供的第一条数据的索引。
查看初始化循环:
for (loopCount = REMAINING; loopCount < LUNCH_ITEMS; ++loopCount)
{
// The code inside the loop will be executed for
// loopCount being equal to
// REMAINING
// REMAINING + 1
// ....
// LUNCH_ITEMS - 1
//
// So in your case, you execute this code for
// loopCount equal to 2, 3 and 4
}
也就是说循环里面的代码执行了3次,即你调用了3次malloc.
同理,看你释放内存的那个循环
for (loopCount = 0; loopCount < LUNCH_ITEMS; loopCount++)
{
// you execute this code for
// loopCount equal to 0, 1, 2, 3 and 4
// ....
if (loopCount > REMAINING)
{
// Since REMAINING is 2, you execute this code for
// loopCount equal 3 and 4
}
}
所以if
正文中的代码只执行了2次。你真的想做 3 次(即循环计数等于 2、3 和 4)。所以需要把代码改成:
if (loopCount >= REMAINING) // Notice the = sign
{
// Since REMAINING is 2, you execute this code for
// loopCount equal 2, 3 and 4
}
现在关于 malloc
和 free
。当你释放内存时,即使用 free
、 你必须准确传递 malloc
返回给你的值
在初始化时你这样保存了指针:
namePtr = (char *)malloc(exactMemory * sizeof(char));
// ...
(lunch + loopCount)->name = namePtr; // Save pointer
所以free
应该使用(lunch + loopCount)->name
。喜欢:
if (loopCount >= REMAINING) // Notice the = sign
{
free((lunch + loopCount)->name);
// Optional part but always after calling free
(lunch + loopCount)->name = NULL;
}
顺便说一句:请注意
(lunch + loopCount)->name
与
相同
lunch[loopCount].name
许多人认为更容易阅读。
我一直在尝试 free() 最后的内存,但是我的导师说我已经创建了 3 个 malloc 指针(使用当前设置)。
注意:关于 malloc/what 在内存中实际发生的事情,我想要尽可能详细的解释。
如果能指导我如何确保没有内存泄漏,我将不胜感激。
下面是我写的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LUNCH_ITEMS 5
#define REMAINING 2
#define CHAR_SIZE 256
int main(void)
{
struct Food
{
char *name; //name attribute of food
int weight, calories;
} lunch[LUNCH_ITEMS] = {{"apple", 4, 100}, {"salad", 2, 80},};
int loopCount;
//INPUT
char *namePtr = NULL;
for (loopCount = REMAINING; loopCount < LUNCH_ITEMS; ++loopCount)
{
char tempBuffer[CHAR_SIZE];
printf("Enter name of item,the weight of item, and the calories in that item: \n");
// store name string in a tempBuffer. weight and calories directly into lunch structure array address
scanf("%255s %d %d", tempBuffer, &lunch[loopCount].weight, &lunch[loopCount].calories);
// get the exact size of (memory of) the input string including add one for null char
size_t exactMemory = strlen(tempBuffer) + 1;
//dynamically allocate the exact amount of memory determined in the previous step
namePtr = (char *)malloc(exactMemory * sizeof(char));
// check if no memory is allocated for foodPtr
if (namePtr == NULL)
{
fprintf(stderr, "Not enough memory available***\n Terminating Program");
exit(1);
}
//store the pointer to it in the name member of the structure in
//the current lunch array element.
(lunch + loopCount)->name = namePtr;
// Copy the food name (stored in tempbuffer) into the dynamically-allocated
// memory using the memcpy function
memcpy(namePtr, tempBuffer, exactMemory);
//(lunch + loopCount)->name = namePtr;
}
//DISPLAY
printf("Item Weight Cals\n---------------------------------------------\n");
for (loopCount = 0; loopCount < LUNCH_ITEMS; loopCount++)
{
int weight = lunch[loopCount].weight;
int cals = lunch[loopCount].calories;
printf("%-12.20s%22d%11d\n", (lunch + loopCount)->name, weight, cals);
if (loopCount > REMAINING)
{
//(lunch+loopCount)->name = NULL;
namePtr = NULL;
free(namePtr);
//free((lunch + loopCount)->name);
}
}
//De-allocate all malloc'd memory
return EXIT_SUCCESS;
}
我的输出-
Item Weight Cals
-----------------
apple 4 100
salad 2 80
hello 22 33
maybe 44 45
right 100 200
我认为您的讲师关于 3 个 malloc'ed 字符串的评论是一个非常有力的线索。我注意到您有一个包含 5 个项目的数组,其中预填充了 2 个项目。 5 - 2 是 3.
此外,请注意 C 中的索引从 0 开始。您预先初始化数组的 2 个项目将具有索引 0 和索引 1。索引 2 将是第一个输入的数据。使用 > 2 比较该索引实际上会导致您跳过用户提供的第一条数据的索引。
查看初始化循环:
for (loopCount = REMAINING; loopCount < LUNCH_ITEMS; ++loopCount)
{
// The code inside the loop will be executed for
// loopCount being equal to
// REMAINING
// REMAINING + 1
// ....
// LUNCH_ITEMS - 1
//
// So in your case, you execute this code for
// loopCount equal to 2, 3 and 4
}
也就是说循环里面的代码执行了3次,即你调用了3次malloc.
同理,看你释放内存的那个循环
for (loopCount = 0; loopCount < LUNCH_ITEMS; loopCount++)
{
// you execute this code for
// loopCount equal to 0, 1, 2, 3 and 4
// ....
if (loopCount > REMAINING)
{
// Since REMAINING is 2, you execute this code for
// loopCount equal 3 and 4
}
}
所以if
正文中的代码只执行了2次。你真的想做 3 次(即循环计数等于 2、3 和 4)。所以需要把代码改成:
if (loopCount >= REMAINING) // Notice the = sign
{
// Since REMAINING is 2, you execute this code for
// loopCount equal 2, 3 and 4
}
现在关于 malloc
和 free
。当你释放内存时,即使用 free
、 你必须准确传递 malloc
在初始化时你这样保存了指针:
namePtr = (char *)malloc(exactMemory * sizeof(char));
// ...
(lunch + loopCount)->name = namePtr; // Save pointer
所以free
应该使用(lunch + loopCount)->name
。喜欢:
if (loopCount >= REMAINING) // Notice the = sign
{
free((lunch + loopCount)->name);
// Optional part but always after calling free
(lunch + loopCount)->name = NULL;
}
顺便说一句:请注意
(lunch + loopCount)->name
与
相同lunch[loopCount].name
许多人认为更容易阅读。