简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM