我正在尝试初始化指向0mq上下文和套接字的指针结构的代码上出现分段错误。 main方法中注释掉的代码可以正常工作,但它只使用局部变量。我想初始化它们并在结构中传递它们,但是我的谷歌foo让我无法正确地做到这一点。
#include "zhelpers.h"
#include <stdio.h>
#include <stdlib.h>
#include <zmq.h>
struct publisher{
void *handle;
void *context;
};
void init_publisher(struct publisher *p);
void destroy_publisher(struct publisher *p);
void publish(struct publisher *p,char *msg);
void init_publisher(struct publisher *p)
{
p = (struct publisher *)malloc(sizeof(struct publisher));
p->context = malloc(sizeof(void *));
p->handle = malloc(sizeof(void *));
void *context = zmq_ctx_new();
void *handle = zmq_socket(context,ZMQ_PUB);
zmq_bind(handle, "tcp://*:5556");
zmq_bind(handle, "ipc://feed.ipc");
p->context = context;
p->handle = handle;
}
void destroy_publisher(struct publisher *p)
{
zmq_close(p->handle);
zmq_ctx_destroy(p->context);
free(p->handle);
free(p->context);
free(p);
}
void publish(struct publisher *p,char *msg)
{
s_send(p->handle, msg);
}
int main(void)
{
/**
void *context = zmq_ctx_new();
void *publisher = zmq_socket(context, ZMQ_PUB);
int rc = zmq_bind(publisher, "tcp://*:5556");
assert(rc == 0);
rc = zmq_bind(publisher, "ipc://weather.ipc");
assert(rc == 0);
printf("Started Weather Server...\n");
srandom((unsigned) time (NULL));
int zipcode, temperature, relhumidity;
zipcode = randof(100000);
temperature = randof (215) - 80;
relhumidity = randof (50) + 10;
char update[20];
sprintf(update, "%05d %d %d", zipcode, temperature, relhumidity);
s_send(publisher, update);
zmq_close(publisher);
zmq_ctx_destroy(context);
*/
struct publisher *p;
init_publisher(p);
printf("Setup pub\n");
srandom((unsigned) time (NULL));
int zipcode, temperature, relhumidity;
zipcode = randof(100000);
temperature = randof (215) - 80;
relhumidity = randof (50) + 10;
char update[20];
sprintf(update, "%05d %d %d", zipcode, temperature, relhumidity);
publish(p,update);
printf("Published Message\n");
destroy_publisher(p);
printf("Destroyed publisher\n");
return 0;
}
答案 0 :(得分:3)
此代码中似乎没有任何内容会导致崩溃。 (假设您知道所有zmq_...
内容的工作方式。)
如果您准确地告诉我们错误发生的位置会有所帮助,但我的猜测是错误发生在此代码 之外。
你知道,你正在将struct publisher *p
传递给你的init_publisher()
函数,但是你正在为该方法中的p
分配内存,这使得传递p
毫无意义, )然后你没有回来p
。因此,调用init_publisher()
的代码可能需要初始化p
,但事实并非如此。 p
指向的内存只是在init_publisher()
函数中本地分配和泄露。
因此,不要传递p
,而是让函数声明并返回它。
或者,如果来电者已经分配了p
,那么请不要在init_publisher()
内重新分配。
还请注意,语句p->context = malloc(sizeof(void *));
是不必要的,并且它们会泄漏少量内存,因为您将继续覆盖这些结构成员。
答案 1 :(得分:2)
问题是传递的指针和你malloc()
ed的指针不一样。传递的指针包含原始指针的相同地址,可能是一个无效的地址,但是它们自己的poninters的地址是不同的,因为在c中你只能通过值传递一个变量,因此指针被复制。
这意味着当您在函数内部重新分配p
时,函数外部的p
将保持不变。如果它是在外部分配的,那么它就会有所不同,你只需使用该功能来访问它的成员。
你也不需要malloc()
你想要使用的每个指针,问题是在解除引用它之前它必须指向一个有效的地址。如果要请求新的未初始化内存,则使用malloc()
,否则只需使指针指向有效地址,以便定义解除引用它,使用不带malloc()
指针的指针的一个示例是< / p>
int *pointer;
int value;
value = 4;
pointer = &value; // Now `pointer' points to `value's` address
*pointer = 3;
printf("%d\n", value);
编写函数的一种方法是
int
init_publisher(struct publisher **pp)
{
struct publisher *p;
*pp = malloc(sizeof(struct publisher));
if (*pp == NULL)
return -1;
p = *pp;
p->context = zmq_ctx_new();
p->handle = zmq_socket(context,ZMQ_PUB);
if (p->handle != NULL) /* Just in case, do not dereference a NULL pointer */
{
zmq_bind(p->handle, "tcp://*:5556");
zmq_bind(p->handle, "ipc://feed.ipc");
}
return 0;
}
然后你可以像这样使用它
struct publisher *p;
if (init_publisher(&p) != 0)
do_something_there_was_an_error();
/* Continue using `p' */
请注意,函数返回一个值,指示分配是否成功。通常malloc()
不会失败,但这并不意味着您应该忽略可能的失败。
当我说你先分配p
时,我的意思是,如果你改为这样做
struct publisher *p;
p = malloc(sizeof(*p));
if (p == NULL)
return handle_error();
init_publisher(p);
然后init_publisher()
可能
void
init_publisher(struct publisher *pp)
{
void *context;
void *handle;
p->context = zmq_ctx_new();
p->handle = zmq_socket(context,ZMQ_PUB);
if (p->handle != NULL) /* Just in case, do not dereference a NULL pointer */
{
zmq_bind(p->handle, "tcp://*:5556");
zmq_bind(p->handle, "ipc://feed.ipc");
}
}
这可能是你想要做的。