[英]Memory issue in C where data is being overwritten
I've the following program: 我有以下程序:
// 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);
}
as appears in the main method, the function get_parameter should prints abcdefghi
, but it prints abcd?
如出现在main方法中,函数get_parameter应该打印
abcdefghi
,但它打印abcd?
where ?
在
?
is a controls character with value of 17. 是值为17的控件字符。
Why the reset of string is not printed? 为什么不打印字符串重置? I think I mis-used the
malloc
to allocate appropriate space. 我想我滥用了
malloc
来分配适当的空间。
Also, is there any tool that I can use to know the internal representation of memory for my pointers? 另外,有没有什么工具可以用来了解指针的内存的内部表示形式?
You're dealing with C-Strings here. 您在这里处理C字符串。 You must consider 1 additional byte for the NULL-termination ('\\0')
您必须为NULL终止('\\ 0')考虑另外1个字节
Therefore: 因此:
char s[strlen(querystr)] ;
strcpy(s, querystr);
Is incorrect. 是不正确的。
strlen
will return 4 for string "abcd" but what you want is to allocate space for "abcd\\0" strlen
将为字符串“ abcd”返回4,但您要为“ abcd \\ 0”分配空间
So you need strlen + 1 所以你需要strlen + 1
The lines 线
out = (char*) malloc(sizeof(char*));
iout = (char*) malloc(sizeof(char*));
are a problem. 是一个问题。
sizeof()
returns the number of bytes required to store an object of the given type, in this case, the size of a pointer (to a char
). sizeof()
返回存储给定类型的对象所需的字节数,在这种情况下,为指针(指向char
)的大小。 malloc()
then allocates that many bytes (apparently 4 bytes on your architecture). 然后,
malloc()
分配那么多字节(在您的体系结构上显然为4个字节)。 To fix this, you need to give malloc
the desired string length instead of using sizeof
. 要解决此问题,您需要为
malloc
所需的字符串长度,而不是使用sizeof
。
Additionally, the line 另外,这条线
char* value = (char*) malloc(_size*sizeof(char));
has a completely unnecessary use of sizeof()
. 完全没有必要使用
sizeof()
。 sizeof(char)
is guaranteed by the standard to be 1. 该标准保证
sizeof(char)
为1。
You should use gdb to run your binary step by step and see what's wrong. 您应该使用gdb逐步运行二进制文件,然后看看有什么问题。 Valgrind is a very good tools, it will tell you what's line overwrite in memory, etc..
Valgrind是一个非常好的工具,它将告诉您内存中的哪些行被覆盖等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.