我有下面的模型,我需要一些反馈,说明我如何改进url_decode函数,使它更快,使用更少的内存。有几个要求。我必须使用StringArg和StringReturn结构。我还需要完全解码字符串。我知道双重编码的攻击,但是这是用于数据挖掘的,我需要得到完全解码的字符串,因此是while循环。
请看一看函数StringReturn* url_decode(char* line),并建议任何我能做的,以提高速度或减少内存使用。
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <ctype.h>
struct StringArg
{
int length;
char* data;
StringArg(const char* inData)
{
length = strlen(inData);
data = new char[length+1];
strcpy(data, inData);
}
};
struct StringReturn
{
int size;
char* data;
StringReturn(int inSize)
{
size = inSize;
data = new char[size+1];
}
};
StringArg* stringArg(char* line)
{
return new StringArg(line);
}
StringReturn* stringReturnInfo(int size)
{
return new StringReturn(size);
}
StringReturn* url_decode(char* line)
{
StringArg *str;
str = stringArg(line);
int lengths = str->length;
char* urlData = new char[lengths+1];
char* fmt = new char[4];
memcpy(urlData, str->data, str->length);
urlData[lengths] = 0;
bool bFoundChar = false;
int j = 0;
do
{
j = 0;
bFoundChar = false;
for (int i = 0; i < lengths; i++)
{
char ch = urlData[i];
if (ch == '+')
{
urlData[j++] = ' ';
}
else if (ch == '%' && i+2 < lengths && isxdigit(urlData[i+1]) && isxdigit(urlData[i+2]))
{
bFoundChar = true;
fmt = new char[4];
fmt[0] = urlData[++i];
fmt[1] = urlData[++i];
fmt[2] = 0;
urlData[j++] = (char)strtol(fmt, NULL, 16);
}
else {
urlData[j++] = ch;
}
}
lengths = j;
}while (bFoundChar);
StringReturn *ret = stringReturnInfo(j);
ret->size = j;
memcpy(ret->data, urlData, j);
delete urlData;
delete fmt;
return ret;
}
void test_decode(char* line)
{
StringReturn *str = url_decode(line);
printf(str->data);
}
int main(int argc, const char * argv[])
{
test_decode("bob.com?url=http%3A%2F%2Fsteve.com%3Furl%3Dhttp%253A%252F%252Fjohn.com");
return 0;
}发布于 2013-05-13 18:42:03
这注定要失败:
struct StringArg
{
int length;
char* data;
StringArg(const char* inData)
{
length = strlen(inData);
data = new char[length+1];
strcpy(data, inData);
}
};这只会导致灾难。它不太可能比std::string更有效,并且更有可能导致内存泄漏。
使用std::string,它的工作原理是正确的,并且经过了很大程度的优化,您不能用自己的手编写一个字符串。这是一个过早的优化。
同样:
struct StringReturn
{
int size;
char* data;
StringReturn(int inSize)
{
size = inSize;
data = new char[size+1];
}
};不要在周围传递指针:
StringArg* stringArg(char* line)
{
return new StringArg(line);
}使用std::unique_ptr封装指针对象,使其能够正确管理内存。如果您做的事情是正确的,结果代码优化为无操作,如果您不正确地做事情,它会节省您的屁股。实际上,我会丢弃您的字符串类并使用std::string。来自返回的复制构造几乎总是被NRVO所忽略,因此比您想象的要高效得多。
又一样
StringReturn* stringReturnInfo(int size)
{
return new StringReturn(size);
}手动复制C-字符串是非常痛苦的。使用std::string
int lengths = str->length;
char* urlData = new char[lengths+1];
char* fmt = new char[4];
memcpy(urlData, str->data, str->length);
urlData[lengths] = 0;
// Or you can do:
std::string urlData = line;此外,您的代码也不例外安全。
请使用RIAA确保没有泄漏(或者使用std::string已经这样做了)。
在这里可以找到URL的定义:https://www.rfc-editor.org/rfc/rfc3986
假装'+‘是一个空格只在URI的path部分有效,而在URI的查询或片段部分无效,因此扫描整个字符串以获得'+’是不正确的。
我还需要完全解码字符串。我知道双重编码的攻击
该规范不允许双重(或嵌套)编码。如果它解码为另一个'%‘,那么这就是值。你不要试图重新解释这个价值。
https://codereview.stackexchange.com/questions/26103
复制相似问题