我有一个CGI应用程序,我一直在Visual Studio Express 2013中编写,但是我遇到了一个场景,当传递给函数的字符串超过31个字节时程序失败。我会尝试自己调试它,但在Visual Studio Debugger中一切正常,它只在命令提示符中我看到错误。
我相信这是我分配(或未分配)内存的方式。我有一个函数,它接受一个字符串并返回解码后的字符串。
我已经把所有内容都删除到了那个函数和main,所以你可以看到两个案例,一个在CMD中工作,另一个在失败中。
这是文件:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Function: urlDecode
* Purpose: Decodes a web-encoded URL
* Input: const char* str - the URL to decode
* Output: char* - the decoded URL
*/
char *urlDecode(const char *str) {
int d = 0; /* whether or not the string is decoded */
char *dStr = malloc(strlen(str) + 1);
char *eStr = malloc(2); /* a hex code */
strcpy(dStr, str);
while (!d) {
d = 1;
int i; /* the counter for the string */
int j = strlen(dStr);
for (i = 0; i<j; ++i) {
if (dStr[i] == '%') {
if (dStr[i + 1] == 0)
return dStr;
if (isxdigit(dStr[i + 1]) && isxdigit(dStr[i + 2])) {
d = 0;
//combine the next two numbers into one
eStr[0] = dStr[i + 1];
eStr[1] = dStr[i + 2];
//convert it to decimal
long int x = strtol(eStr, NULL, 16);
//remove the hex
memmove(&dStr[i], &dStr[i + 2], strlen(dStr) - 1);
dStr[i] = x;
j = j - 2;
}
}
}
}
free(eStr);
return dStr;
}
int main(void)
{
//this one runs fine from command prompt
char *test1 = "s=W3%20%3A%20SVC&action=stop";
printf("%s\n", test1);
char *decoded1 = urlDecode(test1);
printf("%s\n", decoded1);
free(decoded1); //and I can even free the memory
//this one prints in command prompt, but the program crashes immediately after
char *test2 = "service=W3%20%3A%20SVC&action=stop";
printf("%s\n", test2);
char *decoded2 = urlDecode(test2);
printf("%s\n", decoded2);
//when I comment this free out, it debugs fine in VS, but still fails in cmd
//this is the reason I believe it's a memory error
//free(decoded2);
system("PAUSE"); //so I can see what's happening
return 0;
}
答案 0 :(得分:3)
您无法空终止eStr
,并且没有为其分配足够的内存:您需要三个字符,而不是两个字符。
由于eStr
太短,请考虑将其作为堆栈变量,而不是在动态存储上分配它:
char eStr[] = "00";
这将分配足够的空间,并且不必在函数末尾free
指针。
另一个问题是memmove
:看起来您的索引已关闭。您可以修复它,但更容易完全避免memmove
:而不是进行替换,使用str
作为您的来源,dStr
作为您的目的地:< / p>
char *urlDecode(const char *str) {
int d = 0; /* whether or not the string is decoded */
char *dStr = malloc(strlen(str) + 1);
char *ret = dStr;
char eStr[] = "00";
strcpy(dStr, str);
while (!d) {
d = 1;
int i; /* the counter for the string */
int j = strlen(dStr);
for (i = 0; i<j; ++i) {
if (str[i] == '%') {
if (str[i + 1] == 0) {
break;
}
if (isxdigit(str[i + 1]) && isxdigit(str[i + 2])) {
d = 0;
//combine the next two numbers into one
eStr[0] = str[i + 1];
eStr[1] = str[i + 2];
//convert it to decimal
long int x = strtol(eStr, NULL, 16);
*dStr++ = x;
}
} else {
*dStr++ = str[i];
}
}
}
*dStr = 0;
return ret;
}
答案 1 :(得分:2)
应该是
char *eStr = calloc(3,1); /* a hex code */
memmove(&dStr[i+1], &dStr[i + 3], strlen(&dStr[i+3])+1 );