C 队列错误地存储值

C queue incorrectly storing values

我试图在 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);
}

当使用 printqueue() 打印队列时,它每次都打印相同的值(头部值),表明头部在队列中是重复的。

编辑:进行了更多测试,发现整个队列都设置为最后添加的项目。

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);
    }
  }
}

你的队列没问题。问题是您使用相同的指针调用 dispatch 。您不断传递与 header 相同的 struct pcap_pkthdr header; 地址,而 pcap_next 的手册是这样说的:

pcap_next() reads the next packet (by calling pcap_dispatch() with a cnt of 1) and returns a u_char pointer to the data in that packet. The packet data is not to be freed by the caller, and is not guaranteed to be valid after the next call to pcap_next_ex(), pcap_next(), pcap_loop(), or pcap_dispatch(); if the code needs it to remain valid, it must make a copy of it. The pcap_pkthdr structure pointed to by h is filled in with the appropriate values for the packet.

对于它们两者,解决方案是相同的:您需要 malloc 每次调用 dispatch 的新指针,并将数据复制到它们中。