Home > database >  Need help fixing a malloc overwriting a variable
Need help fixing a malloc overwriting a variable

Time:12-14

i'm a student and I'am required to write some function, however one of my function which is "like" a strjoin is overwriting a buffer at some point and I don't understand why, there is no memory leaks so it should not be happening but I don't believe the error could be on the compilator part.

There is the code of my function: `

char    *ft_strnjoin(char *s1, const char * const s2, size_t n)
{
    char    *new;
    size_t  s1len;
    size_t  s2len;

    if (!s2)
        return (NULL);
    s1len = ft_strlen(s1);
    s2len = ft_strlen(s2);
    if (!s2len)
        return (s1);
    if (s2len > n)
        s2len = n;
    new = malloc(s1len   s2len   1);
    if (!new && !s1)
        return (NULL);
    else if (!new)
        return (free(s1), NULL);
    ft_memset(new, 0, s1len   s2len   1);
    ft_memcpy(new, s1, s1len);
    ft_memcpy(new   s1len, s2, s2len);
    return (free(s1), new);
}

Ps: ft_strlen, fr_memcpy and ft_memset behare exactly the same as the standard one exept that they chekc for a NULL before, it is required as my ft_strnjoin can accept a NULL s1.

This is what gdb show me: at ft_strnjoin(s1: 0X0, S2: 0X55...596d9 = '0', n: 42) the line before new = malloc(s1len s2len 1); s2 is 0x55...596d9 which point to ['0', 0], s1len = 0 and s2len = 1 after this line, when the malloc have been executed, the same s2 is now 0x55...596d9 (address is the same) but now point to ['l', \371, \367, \377, \177].

I have absolutely no idea about what is happening... RePs: s2 is on the stack

I tried debugging with gdb, which failed. I tried changing compilator the issue persisted, I tried upgrading my system package and using another computer.

CodePudding user response:

I would not use memcpy/memmove at all in this case:

char *ft_strnjoin(char *s1, const char * const s2, size_t n)
{
    char    *new;
    size_t  s1len = s1 ? strlen(s1) : 0;
    size_t  s2len = s2 ? strlen(s2) : 0;

    if((s1len   s2len) && n)
    {
        new = malloc(n = ((s1len   s2len) < n ? (s1len   s2len   1) : n));
        if(new)
        {
            char *wrk = new;
            size_t i = 0;
            if(s1) while(--n && *s1) *wrk   = *s1  ;
            if(s2 && n) while(n-- && s2[i]) *wrk   = s2[i  ];
            *wrk = 0;
        }
    }
    return new;
}


int main(void)
{
    char *s1 = "Hello ";
    char *s2 = "world";
    char *s3;

    printf("`%s`\n", (s3 = ft_strnjoin(s1,s2,8)) ? s3 : "NULL");
    free(s3);
    printf("`%s`\n", (s3 = ft_strnjoin(s1,s2,1)) ? s3 : "NULL");
    free(s3);
    printf("`%s`\n", (s3 = ft_strnjoin(s1,s2,0)) ? s3 : "NULL");
    free(s3);
    printf("`%s`\n", (s3 = ft_strnjoin(s1,s2,14)) ? s3 : "NULL");
    free(s3);
    printf("`%s`\n", (s3 = ft_strnjoin(s1,NULL,11)) ? s3 : "NULL");
    free(s3);
    printf("`%s`\n", (s3 = ft_strnjoin(NULL,s2,11)) ? s3 : "NULL");
    free(s3);
    printf("`%s`\n", (s3 = ft_strnjoin(NULL,NULL,11)) ? s3 : "NULL");
    free(s3);
}

CodePudding user response:

Hi thank for the replies, the error was quite stupid and the code I posted was in fact irrelevant.

I was reallocating some memory at some point and in this case s2 was a pointer over a buffer that have been moved. So my buffer changed position, s2 was still pointing over the freed memory and malloc was allocating that piece of memory. That was why malloc was "changing" s2 contents...

I'll remember, if some buffer have the slightest change of being moved I must iterate over it using an index and not a pointer.

Thank you everyone !

  • Related