简体   繁体   English

Valgrind错误。 在函数中使用malloc和realloc

[英]Valgrind errors. Use of malloc and realloc in functions

I am trying to make mystrcat function to work. 我正在尝试使mystrcat函数正常工作。 It seems to return right string but valgrind gives errors on my code which I cant seem to fix. 它似乎返回正确的字符串,但是valgrind给出了我似乎无法修复的代码错误。

char *mystrcat(char *dest, const char *src) {
    int len = strlen(dest) * 2;
    char *origdest = realloc(dest, len);
    while(*dest) {
        dest++;
    }

    while (*src) {
        *dest++ = *src++;
    }
    return origdest; 
}

int main(void) {
    char *str = malloc(7);
    strcpy(str, "First");

    str = mystrcat(str, "Second");
    printf("%s\n", str);
    free(str);
}

Valgrind errors which I don't understand: 我不明白的Valgrind错误:

==10== Invalid read of size 1
==10==    at 0x40068B: mystrcat (mystrcat.c:9)
==10==    by 0x40070F: main (mystrcat.c:25)
==10==  Address 0x5203040 is 0 bytes inside a block of size 7 free'd
==10==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10==    by 0x40067B: mystrcat (mystrcat.c:8)
==10==    by 0x40070F: main (mystrcat.c:25)
==10==  Block was alloc'd at
==10==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10==    by 0x4006E6: main (mystrcat.c:22)
==10== 
==10== Invalid write of size 1
==10==    at 0x4006AF: mystrcat (mystrcat.c:14)
==10==    by 0x40070F: main (mystrcat.c:25)
==10==  Address 0x5203046 is 6 bytes inside a block of size 7 free'd
==10==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10==    by 0x40067B: mystrcat (mystrcat.c:8)
==10==    by 0x40070F: main (mystrcat.c:25)
==10==  Block was alloc'd at
==10==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10==    by 0x4006E6: main (mystrcat.c:22)

You need this (see comments for explanations): 您需要这个(请参阅注释以获取解释):

char *mystrcat(char *dest, const char *src) {
    int len = strlen(dest) * 2;
    char *newdest = realloc(dest, len);
    // newdest contains the pointer to the newly allocated memory
    // and dest is now no longer valid

    dest = newdest;
    while(*dest) {
        dest++;
    }

    // now dest points to the end of the string in the newly
    // allocated memory

    while (*src) {
        *dest++ = *src++;
    }

    // add NUL terminator
    *dest = 0;

    // we return the newly allocated memory
    return newdest;  
}

But this function is still not entirely correct. 但是此功能仍不完全正确。

This is wrong: 这是错误的:

int len = strlen(dest) * 2;

Doubling the size is wrong, because if src is longer than the length of the dest string, there won't be enough memory and you'll get a buffer overflow. 将大小加倍是错误的,因为如果src大于dest字符串的长度,则将没有足够的内存,并且您将获得缓冲区溢出。

The memory size needed for the concatenated string is: 串联字符串所需的内存大小为:

size of the original string + size of the string to be concatenated + 1

The +1 is needed because of the NUL string terminator. 由于NUL字符串终止符,因此需要+1

You therefore need this: 因此,您需要:

int len = strlen(dest) + strlen(src) + 1;

And another thing: 还有一件事:

char *mystrcat(char *dest, const char *src)

can be replaced by 可以替换为

char *mystrcat(const char *dest, const char *src)

because we actually don't modify the memory pointed by dest . 因为我们实际上不修改dest指向的内存。

Be aware that your mystrcat only works if the destinatino pointer has been allocated with a malloc -like function. 请注意,只有在已使用类似malloc的函数分配了destinatino指针的情况下,您的mystrcat才有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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