malloc 和 calloc 的使用区别
gcc 4.5.1 c89
我编写这个源代码是为了更好地理解 malloc 和 calloc。
我明白了,但有几个问题想请教一下。
dev = malloc(number * sizeof *devices);
等于这个calloc。我不关心清除内存。
dev = calloc(number, sizeof *devices);
与在 while 循环中执行 5 次相比,这到底是什么:
dev = malloc(sizeof *devices);
我猜第一个和第二个是创建一个指向 5 结构设备的指针。第三个是创建一个指向结构设备的单个指针?
我的程序说明了使用 valgrind --leak-check=full 编译和运行的 3 种不同方法。
非常感谢您的任何建议。
#include <stdio.h>
#include <stdlib.h>
struct Devices {
#define MAX_NAME_SIZE 80
size_t id;
char name[MAX_NAME_SIZE];
};
struct Devices* create_device(struct Devices *dev);
void destroy_device(struct Devices *dev);
int main(void)
{
size_t num_devices = 5;
size_t i = 0;
struct Devices *device = NULL;
struct Devices *dev_malloc = NULL;
struct Devices *dev_calloc = NULL;
for(i = 0; i < num_devices; i++) {
device = create_device(device);
/* Assign values */
device->id = i + 1;
sprintf(device->name, "Device%zu", device->id);
/* Print values */
printf("ID ----- [ %zu ]\n", device->id);
printf("Name --- [ %s ]\n", device->name);
/* Test free */
destroy_device(device);
}
printf("\n");
dev_malloc = malloc(num_devices * sizeof *dev_malloc);
for(i = 0; i < num_devices; i++) {
/* Assign values */
dev_malloc->id = i + 1;
sprintf(dev_malloc->name, "dev_malloc%zu", dev_malloc->id);
/* Print values */
printf("ID ----- [ %zu ]\n", dev_malloc->id);
printf("Name --- [ %s ]\n", dev_malloc->name);
}
/* Test free */
destroy_device(dev_malloc);
printf("\n");
dev_calloc = calloc(num_devices, sizeof *dev_calloc);
for(i = 0; i < num_devices; i++) {
/* Assign values */
dev_calloc->id = i + 1;
sprintf(dev_calloc->name, "dev_calloc%zu", dev_calloc->id);
/* Print values */
printf("ID ----- [ %zu ]\n", dev_calloc->id);
printf("Name --- [ %s ]\n", dev_calloc->name);
}
/* Test free */
destroy_device(dev_calloc);
return 0;
}
struct Devices* create_device(struct Devices *dev)
{
/* Not checking for memory error - just simple test */
return dev = malloc(sizeof *dev);
}
void destroy_device(struct Devices *dev)
{
if(dev != NULL) {
free(dev);
}
}
gcc 4.5.1 c89
I have written this source code for my better understanding of malloc and calloc.
I understand, but just have a few questions.
dev = malloc(number * sizeof *devices);
is equal to this calloc. I am not concerned about clearing the memory.
dev = calloc(number, sizeof *devices);
What is that exactly, compared to doing this 5 times in a while loop:
dev = malloc(sizeof *devices);
I guess the first one and the second is creating a pointer to 5 struct device. And the third is creating a single pointer to a struct device?
My program illustrates this 3 different methods compiled and ran with valgrind --leak-check=full.
Many thanks for any advice.
#include <stdio.h>
#include <stdlib.h>
struct Devices {
#define MAX_NAME_SIZE 80
size_t id;
char name[MAX_NAME_SIZE];
};
struct Devices* create_device(struct Devices *dev);
void destroy_device(struct Devices *dev);
int main(void)
{
size_t num_devices = 5;
size_t i = 0;
struct Devices *device = NULL;
struct Devices *dev_malloc = NULL;
struct Devices *dev_calloc = NULL;
for(i = 0; i < num_devices; i++) {
device = create_device(device);
/* Assign values */
device->id = i + 1;
sprintf(device->name, "Device%zu", device->id);
/* Print values */
printf("ID ----- [ %zu ]\n", device->id);
printf("Name --- [ %s ]\n", device->name);
/* Test free */
destroy_device(device);
}
printf("\n");
dev_malloc = malloc(num_devices * sizeof *dev_malloc);
for(i = 0; i < num_devices; i++) {
/* Assign values */
dev_malloc->id = i + 1;
sprintf(dev_malloc->name, "dev_malloc%zu", dev_malloc->id);
/* Print values */
printf("ID ----- [ %zu ]\n", dev_malloc->id);
printf("Name --- [ %s ]\n", dev_malloc->name);
}
/* Test free */
destroy_device(dev_malloc);
printf("\n");
dev_calloc = calloc(num_devices, sizeof *dev_calloc);
for(i = 0; i < num_devices; i++) {
/* Assign values */
dev_calloc->id = i + 1;
sprintf(dev_calloc->name, "dev_calloc%zu", dev_calloc->id);
/* Print values */
printf("ID ----- [ %zu ]\n", dev_calloc->id);
printf("Name --- [ %s ]\n", dev_calloc->name);
}
/* Test free */
destroy_device(dev_calloc);
return 0;
}
struct Devices* create_device(struct Devices *dev)
{
/* Not checking for memory error - just simple test */
return dev = malloc(sizeof *dev);
}
void destroy_device(struct Devices *dev)
{
if(dev != NULL) {
free(dev);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(7)
为清楚起见进行了编辑
- 我猜第一个和第二个是创建一个指向 5 结构设备的指针。第三个是创建一个指向结构设备的单个指针?
第一个 malloc(number * sizeof(*devices))
将分配足够的内存来存储 number
个 Device
。正如其他人提到的,您可以将此块视为 Device
数组。您返回的指针将指向块的开头。
int number = 5;
Device *ptr = malloc(number * sizeof(*ptr));
/* stuff */
free(ptr);
第二个使用 calloc
执行相同的操作,同时还将内存初始化为 0。同样,您可以将块视为 Device
数组。
int number = 5;
Device *ptr = calloc(number, sizeof(*ptr));
/* stuff */
free(ptr);
第三个循环 5 次,将产生 5 个不同的指针,指向 5 个不同的块,每个块的大小足以存储一个 Device
。这也意味着 5 个指针中的每一个都必须单独释放
。
Device *ptrs[5];
for(int i = 0; i < 5; ++i)
{
ptrs[i] = malloc(sizeof(*ptrs[i]));
}
/* stuff */
for(int i = 0; i < 5; ++i)
{
free(ptrs[i]);
}
程序中的所有三个循环一次仅使用一个 struct Devices 对象。后者分配额外的内存,就好像它们将使用多个对象一样,但随后继续覆盖该内存的开头。如果您在设置 ID 2 的对象后尝试使用 ID 1 的对象,您会发现不再有任何 ID 1 的对象。
相反,您可以执行类似的操作,将分配的内存视为结构数组:
dev_malloc = malloc(num_devices * sizeof *dev_malloc);
for (i=0; i<num_devices; i++) {
/* Assign values */
dev_malloc[i].id = i + 1;
sprintf(dev_malloc[i].name, "dev_malloc%zu", dev_malloc[i].id);
/* Print values */
printf("ID ----- [ %zu ]\n", dev_malloc[i].id);
printf("Name --- [ %s ]\n", dev_malloc[i].name);
}
free(dev_malloc);
查看 calloc 的实现以了解差异。大概是这样的:
// SIZE_MAX is defined in stdint.h from C99
void *calloc( size_t N, size_t S)
{
void *ret;
size_t NBYTES;
// check for overflow of size_t type
if (N > SIZE_MAX / S) return NULL;
NBYTES = N * S;
ret = malloc( NBYTES);
if (ret != NULL)
{
memset( ret, 0, NBYTES);
}
return ret;
}
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
calloc(a,b)
和malloc(a*b)
是等效的,除了算术溢出或类型问题的可能性以及calloc
code> 确保内存是零字节填充的。分配的内存可用于每个大小为b
的a
元素数组(反之亦然)。另一方面,调用malloc(b)
a
次将产生a
大小为b
的单个对象,其中可以独立释放,并且不在数组中(尽管您可以将它们的地址存储在指针数组中)。希望这有帮助。
calloc(a,b)
andmalloc(a*b)
are equivalent except for the possibility of arithmetic overflow or type issues, and the fact thatcalloc
ensures the memory is zero-byte-filled. Either allocated memory that can be used for an array ofa
elements each of sizeb
(or vice versa). On the other hand, callingmalloc(b)
a
times will results ina
individual objects of sizeb
which can be freed independently and which are not in an array (though you could store their addresses in an array of pointers).Hope this helps.