是否有可能有一个(固定)数组将其元素存储在可执行文件的只读段而不是堆栈中?我提出了这个代码,但不幸的是,它在添加,移动或删除项目时非常不灵活.如何验证字符串是否确实存储在只读段中?我试过readelf -a文件,但它没有列出字符串.
typedef struct {
int len;
int pos[100];
char data[500];
} FixedStringArray;
const FixedStringArray items = {
4,
{ 9, 14, 19, 24 },
"LongWord1Word2Word3Word4"
} ;
char* GetItem(FixedStringArray *array, int idx, int *len) {
if (idx >= array->len) {
/* Out of range */
*len = -1;
return NULL;
}
if (idx > 0) {
*len = array->pos[idx] - array->pos[idx - 1];
return & array->data[array->pos[idx - 1]];
}
*len = array->pos[idx];
return & array->data[0];
}
void …Run Code Online (Sandbox Code Playgroud) send()的手册页显示了MSG_MORE断言行为的标志TCP_CORK.我有一个包装函数send():
int SocketConnection_Write(SocketConnection *this, void *buf, int len) {
errno = 0;
int sent = send(this->fd, buf, len, MSG_NOSIGNAL);
if (errno == EPIPE || errno == ENOTCONN) {
throw(exc, &SocketConnection_NotConnectedException);
} else if (errno == ECONNRESET) {
throw(exc, &SocketConnection_ConnectionResetException);
} else if (sent != len) {
throw(exc, &SocketConnection_LengthMismatchException);
}
return sent;
}
Run Code Online (Sandbox Code Playgroud)
假设我想使用内核缓冲区,我可以使用TCP_CORK,只要有必要就启用,然后禁用它来刷新缓冲区.但另一方面,因此需要额外的系统调用.因此,使用MSG_MORE似乎更适合我.我只需将上面的send()行更改为:
int sent = send(this->fd, buf, len, MSG_NOSIGNAL | MSG_MORE);
Run Code Online (Sandbox Code Playgroud)
根据lwm.net,如果数据包足够大,它们将自动刷新:
如果应用程序在套接字上设置该选项,则内核不会发送短数据包.相反,它会等到有足够的数据出现以填充最大大小的数据包,然后发送它.当TCP_CORK关闭时,任何剩余的数据都将在线路上熄灭.
但本节仅涉及TCP_CORK …
是否有编译器指令,以忽略"从不兼容的指针类型初始化"警告Hardware_MouseDrivers_GPM_Methods和Hardware_MouseDrivers_DevInput_Methods?但是,全局关闭警告不是一种选择.
#include <stdio.h>
/* Mouse driver interface */
typedef struct _Hardware_MouseDriver {
int (*open)(void*, char *);
int (*close)(void*);
int (*poll)(void*);
} Hardware_MouseDriver;
/* GPM */
typedef struct _Hardware_MouseDrivers_GPM {
char *path;
} Hardware_MouseDrivers_GPM;
static int Hardware_MouseDrivers_GPM_Open(Hardware_MouseDrivers_GPM *this, char *path);
static int Hardware_MouseDrivers_GPM_Close(Hardware_MouseDrivers_GPM *this);
static int Hardware_MouseDrivers_GPM_Poll(Hardware_MouseDrivers_GPM *this);
static int Hardware_MouseDrivers_GPM_Open(Hardware_MouseDrivers_GPM *this, char *path) {
printf("GPM: Opening %s...\n", path);
this->path = path;
}
static int Hardware_MouseDrivers_GPM_Close(Hardware_MouseDrivers_GPM *this) {
printf("GPM: Closing %s...\n", this->path);
}
static int Hardware_MouseDrivers_GPM_Poll(Hardware_MouseDrivers_GPM *this) …Run Code Online (Sandbox Code Playgroud) 我在Linux上运行的C中编写了一个单线程异步服务器:套接字是非阻塞的,对于轮询,我使用的是epoll.基准测试显示服务器运行良好,根据Valgrind,没有内存泄漏或其他问题.
唯一的问题是当write()命令被中断时(因为客户端关闭了连接),服务器将遇到EPIPE.我通过使用参数-b运行基准测试实用程序"siege"来人工中断.它连续执行大量请求,这些请求都完美无缺.现在我按CTRL-C并重新启动"围攻".有时我很幸运,服务器无法发送完整的响应,因为客户端的fd无效.正如所料,errno设置为EPIPE.我处理这种情况,在fd上执行close()然后释放与连接相关的内存.现在问题是服务器阻塞并且不再正确回答.这是strace输出:
epoll_wait(4, {{EPOLLIN, {u32=0, u64=0}}}, 128, -1) = 1
accept(3, {sa_family=AF_INET, sin_port=htons(55328), sin_addr=inet_addr("127.0.0.1")}, [16]) = 5
fcntl64(5, F_GETFL) = 0x2 (flags O_RDWR)
fcntl64(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0
epoll_ctl(4, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLERR|EPOLLHUP|EPOLLET, {u32=144039912, u64=144039912}}) = 0
epoll_wait(4, {{EPOLLIN, {u32=144039912, u64=144039912}}}, 128, -1) = 1
read(5, "GET /user/register HTTP/1.1\r\nHos"..., 4096) = 161
send(5, "HTTP/1.1 200 OK\r\nContent-Type: t"..., 106, MSG_NOSIGNAL) = 106 <<<<
send(5, "00001000\r\n", 10, MSG_NOSIGNAL) = -1 EPIPE (Broken pipe) <<<< Why did the previous send() work?
close(5) = 0 …Run Code Online (Sandbox Code Playgroud) 是否有可能有一个元素(结构)数组的值大小不一?
我面临的问题是我不知道如何访问元素,因为它需要强制转换."数组"只包含指向结构的指针.因此我决定选择无效**.由于并非每个元素都属于同一类型,因此类型也需要存储在数组中,以便在不进行粗略猜测的情况下知道要转换的内容.但这听起来效率不高.有没有更有效的方法?