我找到了一个代理,并尝试在 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;
}
最佳答案
这意味着当你调用 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);
此外,在您的函数中,您应该在使用获得的指针之前执行检查,就像在 func 中一样,在使用 srv 之前:
if (srv == nullptr) {
// handle null case
}
关于c 抛出异常 : read access violation. srv 为 nullptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60201027/