C中的内存问题,其中数据被覆盖

时间:2011-02-20 00:13:28

标签: c memory-leaks memory-management

我有以下计划:

// 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来分配适当的空间。

另外,有没有什么工具可以用来知道指针的内存表示?

3 个答案:

答案 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是一个非常好的工具,它会告诉你在内存中覆盖什么行等等。