1

このチュートリアルを使用して、C++ CGI スクリプトを作成しています。ただし、フォームの POST データを読み取ろうとすると、コンパイルされません。

  char* lpszContentLength = getenv("CONTENT_LENGTH");
  char* lpszBuffer;
  int nContentLength = atoi(lpszContentLength);

  lpszBuffer = malloc(lpszContentLength+1);  // allocate a buffer
  memset(lpszBuffer, 0, lpszContentLength+1);  // zero it out

  fread(lpszBuffer,1,lpszContentLength,stdin);  // get data

コンパイラの苦情は次のとおりです。

cgi.cpp: In function ‘int main()’:
cgi.cpp:12: error: invalid conversion from ‘char*’ to ‘size_t’
cgi.cpp:12: error:   initializing argument 1 of ‘void* malloc(size_t)’
cgi.cpp:12: error: invalid conversion from ‘void*’ to ‘char*’
cgi.cpp:13: error: ‘memset’ was not declared in this scope
cgi.cpp:15: error: invalid conversion from ‘char*’ to ‘size_t’
cgi.cpp:15: error:   initializing argument 3 of ‘size_t fread(void*, size_t, size_t, FILE*)’

ここで、ln 12 は「lpszBuffer」で始まるものです。

私は C++ を初めて使用するので、これを修正する方法や、なぜこれが発生するのかわかりません。多分それは時代遅れのコードです... POSTリクエストからデータを読み取るための他のソリューションを喜んで受け入れます。

編集: 皆さんの修正に従ってコードを更新しました。

  char* lpszContentLength = getenv("CONTENT_LENGTH");
  char* lpszBuffer;
  int nContentLength = atoi(lpszContentLength);

  lpszBuffer = (char*)malloc(nContentLength+1);  // allocate a buffer
  memset(lpszBuffer, 0, nContentLength+1);  // zero it out

  fread(lpszBuffer,1,nContentLength,stdin);  // get data

ただし、atoi からまだセグメンテーション違反が発生します。

==23419== Invalid read of size 1
==23419==    at 0x498DA8C: ____strtol_l_internal (strtol_l.c:298)
==23419==    by 0x498D7EF: strtol (strtol.c:110)
==23419==    by 0x498AB60: atoi (atoi.c:28)
==23419==    by 0x8048899: main (in .../cgi.cpp.cgi)
==23419==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

ここで何が問題なのですか?POSTが空白の場合、POSTフォームの送信と関係があると思います...

4

2 に答える 2

1

これは の型キャストの問題C++です。lpszBufferは achar*ですが、 をmalloc返しますvoid*。したがって、にキャストする必要がありますchar*char*また、 (lpszContentLength) を真ではない整数値として使用しようとしていることにも注意してください。これは、他の関数でも更新する必要があります-関数を使用して以前に変換しましたatoi。その値を使用します。

したがって、行は次のようになります

lpszBuffer = (char*)malloc(nContentLength+1);

最後に、 を使用するには、ソース ファイルの先頭にあるmemset必要があります。#include <string.h>

また、良い習慣として (特にスクリプトがかなりの時間実行される場合)、作業freeが終わったら記憶を忘れないでください。つまり、割り当てられたものは、使用しなくなったときにそれを呼び出すmalloc必要があります。freeしたがって、関数全体で使用する場合lpszBufferは、関数の最後で単純に実行しますfree(lpszBuffer);

于 2012-04-26T06:07:58.530 に答える
0

エラー: 'char*' から 'size_t' への変換が無効です</p>

lpszContentLengthこれは、 (これは、char*この場合はおそらく数値を表す文字列) をsize_t(通常は長整数)として使用しようとしたために発生します。これを解決するには、まずlpszContentLength整数値に変換する必要があります。エラーを検出するため、これをお勧めstrtol()します-これは処理する必要があります。

チュートリアルを見ると、すでにatoi(). nContentLength誤って使用しようとしたすべての場所を使用して、このエラーを修正することもできますlpszContentLength。彼らのコードは決してテストされていないに違いありません。

atoi()はエラーを検出しないことに注意してください。そのため、チュートリアルを完了したらstrtol()、適切なエラー チェックを使用して変更することをお勧めします。


エラー: 'void*' から 'char*' への変換が無効です</p>

(char*)これは、malloc の戻り値にキャストがないことが原因です。C++ では、キャストが必要です。

lpszBuffer = (char*)malloc(convertedNumber+1); 

エラー: 'memset' はこのスコープで宣言されていません

これは、memset のヘッダーが含まれていないことが原因です。memsetのman ページには、以下を追加する必要があることが示されています。

#include <string.h>

エラー: 'char*' から 'size_t' への変換が無効です</p>

エラー: 'size_t fread(void*, size_t, size_t, FILE*)' の引数 3 を初期化しています</p>

これらは両方とも、整数型である必要がある場合に、lpszContentLength が文字列であることが原因です。上記の最初のエラーを参照してください。

于 2012-04-26T06:50:56.340 に答える