c Исключение: нарушение прав на чтение. srv был нулевым - PullRequest
0 голосов
/ 13 февраля 2020

Я нашел прокси и пытаюсь запустить его на Выпуске x86. Но я получаю сообщение об ошибке "Исключение: нарушение прав на чтение. Srv был nullptr". Повсюду есть "svr", но когда приходит эта часть кода, добавьте sockfd сервера в fd_set, я получаю эту ошибку. Это мой первый вопрос и мой первый c код. Так что я могу быть немного глупым вопросом.

int sb_poll_server(sb_Server *srv, int timeout) {
  sb_Stream *st, **st_next;
  fd_set fds_read, fds_write;
  sb_Socket max_fd = srv->sockfd;
  struct timeval tv;
  int err;

  /* Init fd_sets */
  FD_ZERO(&fds_read);
  FD_ZERO(&fds_write);

  /* Add server sockfd to fd_set */
  FD_SET(srv->sockfd, &fds_read);

  /* Add streams to fd_sets */
  for (st = srv->streams; st; st = st->next) {
    if (st->state >= STATE_SENDING_STATUS) {
      FD_SET(st->sockfd, &fds_write);
    } else {
      FD_SET(st->sockfd, &fds_read);
    }
    if (st->sockfd > max_fd) max_fd = st->sockfd;
  }

  /* Init timeout timeval */
  tv.tv_sec = timeout / 1000;
  tv.tv_usec = (timeout % 1000) * 1000;

  /* Do select */
  select(max_fd + 1, &fds_read, &fds_write, NULL, &tv);

  /* Get and store current time */
  srv->now = time(NULL);

  /* Handle existing streams */
  st_next = &srv->streams;
  while (*st_next) {
    st = *st_next;

    /* Receive data */
    if (FD_ISSET(st->sockfd, &fds_read)) {
      err = sb_stream_recv(st);
      if (err) return err;
    }

    /* Send data */
    if (FD_ISSET(st->sockfd, &fds_write)) {
      err = sb_stream_send(st);
      if (err) return err;
    }

    /* Check stream against timeout, max request length and max lifetime */
    if (
      (srv->timeout && srv->now - st->last_activity > srv->timeout / 1000) ||
      (srv->max_lifetime &&
       srv->now - st->init_time > srv->max_lifetime / 1000) ||
      (srv->max_request_size && st->recv_buf.len >= srv->max_request_size)
    ) {
      sb_stream_close(st);
    }

    /* Handle disconnect -- destroy stream */
    if (st->state == STATE_CLOSING) {
      *st_next = st->next;
      sb_stream_destroy(st);
      continue;
    }

    /* Next */
    st_next = &(*st_next)->next;
  }

  /* Handle new streams */
  if (FD_ISSET(srv->sockfd, &fds_read)) {
    sb_Event e;
    sb_Socket sockfd;

    /* Accept connections */
    while ( (sockfd = accept(srv->sockfd, NULL, NULL)) != INVALID_SOCKET ) {

#ifdef _WIN32
      /* As the fd_set on windows is an array rather than a bitset, an fd
       * value can never be too large for it; thus this check is omitted */
#else
      /* Check FD size, error if it is larger than FD_SETSIZE */
      if (sockfd > FD_SETSIZE) {
        close(sockfd);
        return SB_EFDTOOBIG;
      }
#endif

      /* Init new stream */
      st = sb_stream_new(srv, sockfd);
      if (!st) {
        close(sockfd);
        return SB_EOUTOFMEM;
      }

      /* Push stream to list */
      st->next = srv->streams;
      srv->streams = st;

      /* Do `connect` event */
      e.type = SB_EV_CONNECT;
      err = sb_stream_emit(st, &e);
      if (err) return err;
    }
  }

  return SB_ESUCCESS;
}

1 Ответ

0 голосов
/ 13 февраля 2020

это означает, что когда вы вызывали sb_poll_server (), srv, который вы дали, это nullptr.

Вы должны опубликовать код, который вызывает вашу функцию, но я предполагаю, что вы сделали:

sb_Server *srv = nullptr;
sb_poll_server(srv, timeout);

но вы должны сделать что-то вроде:

sb_Server srv = {0};
sb_poll_server(&srv,timeout);

или:

sb_Server *srv = malloc(sizeof(sb_Server));
//init srv
sb_poll_server(srv,timeout);
free(srv);

также, всегда в ваших функциях, вы должны выполнить проверку перед использованием указателей Вы получаете, как и в свое удовольствие c, прежде чем использовать srv:

if (srv == nullptr) {
    // handle null case
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...