我是C的新手,想知道我处理的事情是否正确。我正在为http://nginx.com/创建一个模块,我正在为我的模块创建一个状态页面。
现在状态页面将包含一些基本的HTML&表。以下是我创建此代码的一些代码。
// Get size
size =
sizeof("<table>") +
sizeof("<tr><td align=\"right\">enabled:</td><td>YES</td></tr>") +
sizeof("<tr><td align=\"right\">activated:</td><td>YES</td></tr>") +
sizeof("<tr><td align=\"right\">connections/lt:</td><td>") + NGX_ATOMIC_T_LEN + sizeof(" / ") + NGX_ATOMIC_T_LEN + sizeof("</td></tr>") +
sizeof("<tr><td align=\"right\">remain on: xxxx-xx-xx xx:xx:xx GMT</td><td></td></tr>") +
sizeof("</table>");
// Start buffer
b = ngx_create_temp_buf(r->pool, size);
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
// Start chain
out.buf = b;
out.next = NULL;
// Finish buffer
b->last = ngx_sprintf(b->last, "<table>");
b->last = ngx_sprintf(b->last, "<tr><td align=\"right\">enabled:</td><td>%s</td></tr>", alcf->enabled ? "YES" : "NO");
b->last = ngx_sprintf(b->last, "<tr><td align=\"right\">activated:</td><td>%s</td></tr>", alcf->activated ? "YES" : "NO");
b->last = ngx_sprintf(b->last, "<tr><td align=\"right\">connections/lt:</td><td>%uA / %uA</td></tr>", ac, alcf->connections_activate);
b->last = ngx_sprintf(b->last, "<tr><td align=\"right\">remain on:</td><td>");
b->last = !alcf->activatedEndTime ? ngx_sprintf(b->last,"") : ngx_http_cookie_time(b->last, alcf->activatedEndTime);
b->last = ngx_sprintf(b->last, "</td></tr>");
b->last = ngx_sprintf(b->last, "<table>");
这是否是唯一有效的方法,我觉得必须两次编写HTML代码,一次获得膨胀缓冲区的大小,一次实际存储在缓冲区中是错误的。会有任何其他解决方案吗?我试图尽可能保持内存效率。
答案 0 :(得分:3)
请记住:sizeof
是编译时运算符 † ,因此您不会在sizeof
语句中使用任何额外的内存。
所以是的,假设您的编译器甚至进行了少量优化,那么这个效率也是如此。
答案 1 :(得分:1)
我认为您有一个错误的错误 - 您忘记为终止\0
留出空间。
您对sizeof
的使用有效,但会强制您重复HTML的每个部分。有一天,您将更新sprintf
行中的HTML,并忘记更新sizeof
行中的副本,这会导致内存溢出。
更好的方法是保持字符串一次,并使用strlen
来获取大小。
这是一个想法的例子。它远非完美,但它可以节省大部分重复次数。
struct html_part {
const char *text;
size_t extra_len;
};
struct html_part html_parts[] = {
{ "<table>", 0 }
{ "<tr><td align=\"right\">enabled:</td><td>%s</td></tr>", 3-2 } // YES=3, %s=2
...
};
// Calculate the space needed
len = 0;
for (i=0;i<sizeof(html_parts)/sizeof(html_parts[0]);i++) {
len += strlen(html_parts[i].text) + html_parts[i].extra_len;
}
len++; // For the terminating null
...
// Print the data
b->last = ngx_sprintf(b->last, html_parts[0]);
b->last = ngx_sprintf(b->last, html_parts[1], alcf->enabled ? "YES" : "NO");