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返回 a 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(它是 a char*,在这种情况下是可能表示数字的字符串)作为 a size_t(通常是长整数)而引起的。要解决这个问题,您首先需要转换lpszContentLength为整数值。我建议strtol()这样做,因为它会检测错误 - 您需要处理这些错误。

查看教程,他们已经使用atoi(). nContentLength您还可以通过使用他们错误地尝试使用的任何地方来修复此错误lpszContentLength。他们的代码一定从未经过测试。

请注意,atoi()它不会检测错误 - 因此,一旦您完成本教程,strtol()通过适当的错误检查更改为一个很好的学习练习。


错误:从 'void*' 到 'char*' 的无效转换</p>

这是由于缺少对(char*)malloc 返回值的强制转换造成的。在 C++ 中,强制转换是必需的:

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

错误:未在此范围内声明“memset”

这是由于不包括 memset 的标头造成的。memset的手册页告诉您需要添加:

#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 回答