我正在尝试动态初始化队列。这是我的功能。
typedef struct{
int size;
int max_size;
short * eles;
} queue;
void dump_queue(queue *q)
{
//print a bunch of information
}
void init_queue(queue *q, int max_size)
{
q = (queue)malloc(sizeof(queue));
q->size = 0;
q->max_size = max_size;
q->eles = (short *)malloc(max_size * sizeof(short));
int i;
for(i = 0; i < max_size; i++)
q->eles[i] = -1;
dump_queue(q);
}
task_queue是一个全局变量。例程的结构如下:(不是确切的代码)
//globally defined here but not initialized
queue * task_queue;
void init_scheduler()
{
init_queue(task_queue, 32);
dump_queue(task_queue);
//other staff
}
注意有两个dump_queue,一个是init_queue(),另一个是init_queue之后。由于task_queue是malloced,我希望dump_queue的两次调用应该给出相同的结果。但第二个实际上报告了一个SIG_FAULT。
在我检查之后,在dump_queue的第二次调用中,task_queue实际上是NULL。那是为什么?
答案 0 :(得分:5)
为什么不呢?您正在init_queue()
的函数本地范围中分配内存。
返回指针的范围有效,但赋值无效。
q = malloc(sizeof(queue));
此q
不会在init_queue()
函数之外保留它的值。
如果queue * task_queue;
是全局的,是否真的需要将其作为函数参数传递?
另外,请注意do not cast malloc()
的返回值。
编辑:
不,auto-free()
中没有c
概念。如果不是free()
- d,应用程序会明确地导致内存泄漏。
答案 1 :(得分:2)
您永远不会向task_queue
分配任何内容。请注意,您已按值而不是引用将task_queue
传递给init_queue
。您应该修改init_queue
以返回queue *
,或者修改其第一个参数以获取queue **
并从&task_queue
传递init_scheduler
。
也许是最简单的解决方案,因为它是全球性的,只需在task_queue = q;
结束时init_queue
。
答案 2 :(得分:1)
它应该是init_queue(&amp; task_queue);或task_queue = init_queue();
答案 3 :(得分:0)
如果你只使用这个函数来初始化task_queue你应该这样做
void init_global_queue(int max_size)
{
queue *task_queue = malloc(sizeof(queue));
task_queue->size = 0;
task_queue->max_size = max_size;
task_queue->eles = malloc(max_size * sizeof(short));
int i;
for(i = 0; i < max_size; i++)
task_queue->eles[i] = -1;
}
但不幸的是,这不是一个好的模式,因为你不能多次使用这个功能
我认为最好的方法就是这样
queue *init_queue(int max_size)
{
queue *q = malloc(sizeof(queue));
q->size = 0;
q->max_size = max_size;
q->eles = malloc(max_size * sizeof(short));
int i;
for(i = 0; i < max_size; i++)
q->eles[i] = -1;
return q;
}
当你想要初始化任何队列时,你只需要调用这个函数
queue * task_queue;
void init_scheduler()
{
task_queue = init_queue(32);
dump_queue(task_queue);
}
还有两件事:
使用malloc调用的返回值并不是很糟糕,事实上无论是显式还是隐式地进行了它的转换
- 执行malloc和(对于此示例)返回其值的最佳方法是这样的:
type *my_pointer = NULL;
my_pointer = malloc(sizeof (type))
if (my_pointer == NULL)
return NULL;
my_pointer->foo = 0;
my_pointer->bar = NULL;
...
return my_pointer
因此,如果malloc无法正常工作(例如:如果你的RAM已满,malloc将返回NULL(并将errno设置为ENOMEM)),你可以正确退出程序
如果您喜欢极简主义编程,您可以这样做;)
type *my_pointer = NULL;
if (!(my_pointer = malloc(sizeof (type))))
return NULL;
更多?男子malloc,男子错误