我一直在使用this tutorial制作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是空白的......
答案 0 :(得分:1)
这是C++
的类型转换问题。 lpszBuffer
是char*
,但malloc
返回void*
。所以你需要把它投射到char*
。另请注意,您尝试将char*
(lpszContentLength)用作整数值,这不是真的。这也必须在您的其他函数中更新 - 您已使用atoi
函数更早地进行了转换;所以要使用这个值。
所以该行应该是
lpszBuffer = (char*)malloc(nContentLength+1);
最后,要使用memset
,您必须在源文件的开头#include <string.h>
。
此外,作为良好的做法(特别是如果脚本运行了很长时间),完成后不要忘记free
你的记忆。也就是说,当您不再使用它时,分配有malloc
的任何内容都应该free
调用它。因此,如果您在整个函数中使用lpszBuffer
,则在函数末尾只需执行free(lpszBuffer);
答案 1 :(得分:0)
错误:从“char *”无效转换为“size_t”
这是因为尝试使用lpszContentLength
(这是一个char*
,在这种情况下是一个可能代表数字的字符串),作为size_t
(通常是一个长整数) )。要解决此问题,首先需要将lpszContentLength
转换为整数值。我建议使用strtol()
,因为它会检测错误 - 您需要处理这些错误。
看一下教程,他们已经使用atoi()
转换了它。您也可以使用nContentLength
错误地尝试使用lpszContentLength
的任何地方来解决此错误。他们的代码必须从未经过测试。
请注意,atoi()
未检测到错误 - 因此,一旦完成本教程,通过适当的错误检查更改为strtol()
将是一个很好的学习练习。
错误:无效转换为'void *'到'char *'
这是因为错过了对malloc返回值的强制转换为(char*)
。在C ++中,需要强制转换:
lpszBuffer = (char*)malloc(convertedNumber+1);
错误:未在此范围内声明'memset'
这是因为不包括memset的标头。 man page for memset告诉您需要添加:
#include <string.h>
错误:从“char *”无效转换为“size_t”
错误:初始化'size_t fread(void *,size_t,size_t,FILE *)'的参数3
这些都是由lpszContentLength是一串字符引起的,当它需要是一个整数类型时。请参阅上面的第一个错误。