我有以下计划:
// required include statements...
static char ***out;
char* get_parameter(char* key)
{
char *querystr = /*getenv("QUERY_STRING")*/ "abcdefg=abcdefghi";
if (querystr == NULL)
return (void*)0;
char s[strlen(querystr)] ;
strcpy(s, querystr);
const char delim = '&';
const char delim2 = '=';
static size_t size = 0;
if (out == 0)
{
out = (char*) malloc(sizeof(char*));
size = split(s, &delim, out);
}
int i=0;
for (; i<size; i++)
{
if ((*out)[i] != NULL)
{
char ***iout = NULL;
iout = (char*) malloc(sizeof(char*));
int isize = split((*out)[i], &delim2, iout);
if (isize > 1 && ((*iout)[1]) != NULL && strcmp(key, (*iout)[0]) == 0)
{
size_t _size = strlen((*iout)[1]);
char* value = (char*) malloc(_size*sizeof(char));
strcpy(value, (*iout)[1]);
free(iout);
return value;
}
}
}
return (void*) 0;
}
static size_t count(const char *str, char ch)
{
if (str == NULL) return 0;
size_t count = 1;
while (*str)
if (*str++ == ch) count++;
return count;
}
size_t split(const char *const str, const char* delim, char ***out)
{
size_t size = count(str, *delim);
*out = calloc(size, sizeof(char));
char* token = NULL;
char* tmp = (char*) str;
int i=0;
while ((token = strtok(tmp, delim)) != NULL)
{
tmp = NULL;
(*out)[i] = (char*) malloc(sizeof strlen(token));
strcpy((*out)[i++], token);
}
return size;
}
main()
{
char* val = get_parameter("abcdefg");
printf("%s\n", val); // it should prints `abcdefghi`, but it prints `abcd?`
free(val);
}
如主方法中所示,函数get_parameter应打印abcdefghi
,但它会打印abcd?
,其中?
是一个值为17的控件字符。
为什么不打印字符串重置?我想我错误地使用了malloc
来分配适当的空间。
另外,有没有什么工具可以用来知道指针的内存表示?
答案 0 :(得分:4)
你在这里处理C-Strings。您必须为NULL终止('\ 0')
考虑另外一个字节因此:
char s[strlen(querystr)] ;
strcpy(s, querystr);
不正确。
strlen
将为字符串“abcd”返回4,但你想要的是为“abcd \ 0”分配空间
所以你需要strlen + 1
答案 1 :(得分:0)
行
out = (char*) malloc(sizeof(char*));
iout = (char*) malloc(sizeof(char*));
是个问题。
sizeof()
返回存储给定类型对象所需的字节数,在本例中为指针大小(到char
)。 malloc()
然后分配那么多字节(显然是你的架构上的4个字节)。要解决此问题,您需要为malloc
提供所需的字符串长度,而不是使用sizeof
。
此外,该行
char* value = (char*) malloc(_size*sizeof(char));
完全不必要地使用sizeof()
。标准保证sizeof(char)
为1。
答案 2 :(得分:0)
您应该使用gdb逐步运行二进制文件,看看有什么问题。 Valgrind是一个非常好的工具,它会告诉你在内存中覆盖什么行等等。