Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C队列错误地存储值_C_Queue - Fatal编程技术网

C队列错误地存储值

C队列错误地存储值,c,queue,C,Queue,我试图在C中设置一个队列,但是当一些新的东西排队时,它每次都会复制head值,而不是存储新的项 #include <pcap.h> #include <pthread.h> #include <stdlib.h> struct packet_queue { struct pcap_pkthdr *header; unsigned char *packet; struct packet_queue *next; }; struct packet_

我试图在C中设置一个队列,但是当一些新的东西排队时,它每次都会复制head值,而不是存储新的项


#include <pcap.h>
#include <pthread.h>
#include <stdlib.h>

struct packet_queue {
  struct pcap_pkthdr *header;
  unsigned char *packet;
  struct packet_queue *next;
};
struct packet_queue *head = NULL;
struct packet_queue *tail = NULL;

int run = 0;
int packets = 0;
int v;


void enqueue(struct packet_queue *pq) {
  if (head == NULL) {
    head = pq;
  }
  else {
    struct packet_queue *current = head;
    while (current->next != NULL) {
      current = current->next;
    }
    current->next = pq;
  }
  packets++;
}


void printqueue() {
  struct packet_queue * current = head;
  int i = 50;
  while (i > 0 && current != NULL) {
    printf("%d\n", current->header->len);
    current = current->next;
    i--;
  }
}

void dispatch(struct pcap_pkthdr *header,
              const unsigned char *packet,
              int verbose) {
  v = verbose;
  int i;

  struct packet_queue *next_packet = (struct packet_queue *) malloc(sizeof(struct packet_queue));
  next_packet->header = (struct pcap_pkthdr *) header;
  next_packet->packet = (unsigned char * ) packet;
  next_packet->next = NULL;
  enqueue(next_packet);
}

你的队伍排得很好。问题是您使用相同的指针调用
dispatch
。您不断传递相同
struct pcap\u pkthdr头的地址作为
标题
,并且
pcap\u next
的手册中说明:

pcap_next()读取下一个数据包(通过调用cnt为1的pcap_dispatch()),并返回指向该数据包中数据的u_char指针。调用者不会释放数据包数据,并且不能保证在下次调用pcap_next_ex()、pcap_next()、pcap_loop()或pcap_dispatch()后数据包数据有效;如果代码需要它保持有效,它必须复制它。h所指向的pcap_pkthdr结构将填充相应的数据包值


对于这两个问题,解决方案都是一样的:每次调用
dispatch
,都需要
malloc
新的指针,并将数据复制到它们中。

与当前问题无关,但将
常量unsigned char*
强制转换为
unsigned char*
不是一个好主意。调用
dispatch
是什么?
header
packet
在哪里被分配?@JosephSible.com我已经在结构中添加了const谢谢!我编辑了一个问题,添加了调度调用的位置“调用方不会释放结构pcap_pkthdr和数据包数据,并且在下次调用pcap_next_ex()、pcap_next()、pcap_loop()或pcap_dispatch()后,这些数据包不保证有效。”;如果代码需要它们保持有效,它必须复制它们。”抱歉,仍然有点困惑。在调用dispatch之前,这会在第二个代码段中吗?或者我必须在分派功能中复制一份吗?@finn_101无论你在哪里做,只要你做就行了。这很有意义。复制常量unsigned char*的最佳方法是什么?@finn_101如果它是以NUL结尾的字符串,那么
strdup
。如果它只是一个字节数组,那么
malloc
后跟
memcpy
。如何检索数据的大小?我正在尝试strlen(packet)
,但每次结果都是1或2,这显然是不正确的
struct pcap_pkthdr header;
  const unsigned char *packet;

  //initialise dynamic array
  dynarray_init(&syn_adds, 5);

  while (1) {
    // Capture a  packet
    packet = pcap_next(pcap_handle, &header);
    if (packet == NULL) {
      // pcap_next can return null if no packet is seen within a timeout
      if (verbose) {
        printf("No packet received. %s\n", pcap_geterr(pcap_handle));
      }
    } else {
      // Optional: dump raw data to terminal
      if (verbose) {
         //dump(packet, header.len);
      }
      // Dispatch packet for processing
      dispatch(&header, packet, verbose);
    }
  }
}