开发者

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? where ? is a controls character with value of 17.

Why the reset of string is not printed? I think I mis-used the malloc to allocate appropriate space.

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. You must consider 1 additional byte for the NULL-termination ('\0')

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"

So you need 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). malloc() then allocates that many bytes (apparently 4 bytes on your architecture). To fix this, you need to give malloc the desired string length instead of using sizeof.

Additionally, the line

char* value = (char*) malloc(_size*sizeof(char));

has a completely unnecessary use of sizeof(). sizeof(char) is guaranteed by the standard to be 1.


You should use gdb to run your binary step by step and see what's wrong. Valgrind is a very good tools, it will tell you what's line overwrite in memory, etc..

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜