1

私は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コードを2回記述しなければならないのは間違っていると思います。1回はバッファを膨らませるサイズを取得し、もう1回は実際にバッファに格納します。これに対する他の解決策はありますか?私はそれを可能な限りメモリ効率を維持しようとしています。

4

2 に答える 2

3
于 2012-06-27T16:21:10.587 に答える
1

オフバイワンエラーがあると思います-終了するためのスペースを確保するのを忘れました\0

作品の使用法ですsizeofが、HTMLの各部分を繰り返す必要があります。ある日、行のHTMLをsprintf更新し、行のコピーを更新するのを忘れるとsizeof、メモリオーバーランが発生します。

より良い方法は、文字列を1回保持し、を使用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");
于 2012-06-27T19:10:31.837 に答える