我尝试获取0mq消息的单个部分,它的工作原理与预期的一样。
但是,如果我用valgrind测试程序,则会得到:


  == 9436 ==条件跳转或移动取决于未初始化的值
  
  == 9436 == at 0x4C2E128:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  
  == 9436 ==通过0x401023:主(werft.c:73)
  
  == 9436 ==
  
  == 9436 ==条件跳转或移动取决于未初始化的值
  
  == 9436 == at 0x4C2E128:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  
  == 9436 ==通过0x401048:主(werft.c:74)
  
  == 9436 ==
  
  == 9436 ==条件跳转或移动取决于未初始化的值
  
  == 9436 == at 0x4C2E128:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  
  == 9436 ==通过0x538B7F9:vfprintf(在/usr/lib/libc-2.25.so中)
  
  == 9436 ==通过0x53B246F:vsnprintf(在/usr/lib/libc-2.25.so中)
  
  == 9436 ==通过0x5391F5E:snprintf(在/usr/lib/libc-2.25.so中)
  
  == 9436 ==通过0x40106F:主(werft.c:74)


我的代码是:

#define DEVICE_IDENTITY "de.logicway.pferdepflug"


int main()
{


    char *incoming[2];

    void *context = zmq_ctx_new();

    void *responder = zmq_socket(context, ZMQ_ROUTER);
    zmq_bind(responder, "tcp://127.0.0.1:9990");


    void *requester = zmq_socket(context, ZMQ_DEALER);
    zmq_setsockopt(requester, ZMQ_IDENTITY, DEVICE_IDENTITY, strlen(DEVICE_IDENTITY));
    zmq_connect(requester, "tcp://127.0.0.1:9990");

    zmq_send(requester, "testfahrt", 9, 0);

    zmq_msg_t received;
    zmq_msg_init(&received);

    int i = 0;
    do {


        int size = zmq_msg_recv(&received, responder, 0);
        char *buffer = (char*) zmq_msg_data(&received);
        incoming[i] = (char*) malloc(strlen(buffer) +1 * sizeof(char*));
        snprintf(incoming[i], strlen(buffer) +1, "%s", buffer);

        i++;

    } while(zmq_msg_more(&received));


    printf("Identifier: %s\n", incoming[0]);
    printf("Message: %s\n", incoming[1]);

    free(incoming[0]);
    free(incoming[1]);

    zmq_msg_close(&received);
    zmq_close(requester);
    zmq_close(responder);
    zmq_ctx_destroy(context);
    return 0;
}


(这不会像现在那样投入生产,这只是让我了解0mq)

由于代码按“原样”工作,因此统一值可能没有问题。但是,这仍然困扰着我。

问题:


在这种情况下应该打扰我吗? (是的,我知道,通常应该总是;))
并且是zmq_msg_t中收到的所有麻烦的根源; /
zmq_msg_init(&received);部分?
如果没有,它在哪里以及如何修复?


非常感谢您的提前帮助!

最佳答案

第1部分:

Valgrind提到strlen正在使用未初始化的内存。在您的情况下,参数是buffer,该参数是从zmq库检索的。

也许您应该检查所涉及的函数调用的返回值。

编辑:我选错了API函数。删除了这部分。



第2部分:

如前所述,您还弄乱了分配:

incoming[i] = (char*) malloc(strlen(buffer) +1 * sizeof(char*));


您不需要char *类型的元素,而只需要char类型的元素。而+1属于长度:

incoming[i] = (char*) malloc((strlen(buffer) +1) * sizeof(char));


鉴于将sizeof (char)定义为1的事实以及不对malloc的返回值进行强制转换的规则,我们得到以下信息:

incoming[i] = malloc(strlen(buffer) + 1);


下一步是从buffer复制字符串:

snprintf(incoming[i], strlen(buffer) +1, "%s", buffer);


鉴于您刚刚分配了足够的内存(您可能添加了NULL检查),因此使用snprintf并没有太多好处。
您可以只使用strcpy或只用strdup创建一个副本

09-04 19:36