What triggers the computer to release a Compound literal?

50 Views Asked by At

The problem is in the function insert_envar:

char **get_envaddress(char **envp, char *find)
{  
    int i;  
    int length;

    length = ft_strlen(find);  
    i = 0;  
    while (envp[i])  
    {  
        if (!ft_strncmp(find, envp[i], length))  
            return (&envp[i]);  
        i++;  
    }  
    return (NULL);  
}

char **variable_and_end(char *string)  
{  
    return ((char *[]){envvar, &string[index]});  
}

void insert_envar(char **string, char *varplus, char **envp)  
{  
    char *build;

    *varplus = 0;  
    varplus = (char *)variable_and_end(varplus + 1);  
    envp = get_envaddress(envp, ((char **)varplus)[0]);  
    *envp = ft_strchr(*envp, '=') + 1;  
    free(((char **)varplus)[0]);  
    varplus = ((char **)varplus)[1];  
    build = ft_strjoin(*string, *envp);  
    ft_stradd(&build, varplus);  
    free(*string);  
    *string = build;  
}

The problem here is that when varplus recieves the compound literal, you can print both [0] and [1] and they are perfectly what I expect, but after calling the function get_envaddres the content of varplus is changed, even the memory address of [0] and [1] are changed. I dont see how get_envaddress is touching varplus memory or value at all.

The only thing I was able to theorize is that the computer is moving its stack memory around and messing with the compound literal.

So how am I losing varplus? (I realize there's a million better ways to write this code, this is about understanding the computers behaviour.)

I tried saving both strings in different pointers right after I get them in varplus. The program run like I expect afterwards.

With this:

void insert_envar(char **string, char *varplus, char **envp)
{
    char *build;

    *varplus = 0;  
    varplus = (char *)variable_and_end(varplus + 1);  
    test[0] = ((char **)varplus)[0];  
    test[1] = ((char **)varplus)[1];  
    printf("varplus: [0] = %s\nvarplus: [1] = %s\n", ((char **)varplus)[0], ((char **)varplus[1]);  
    envp = get_envaddress(envp, ((char **)varplus)[0]);  
    printf("varplus: [0] = %s\nvarplus: [1] = %s\n", ((char **)varplus)[0], ((char **)varplus[1]);  
    printf("test: [0] = %s\ntest: [1] = %s\n", test[0], test[1]);  
    *envp = ft_strchr(*envp, '=') + 1;  
    free(((char **)varplus)[0]);  
    varplus = ((char **)varplus)[1];  
    build = ft_strjoin(*string, *envp);  
    ft_stradd(&build, varplus);  
    free(*string);  
    *string = build;  
}

I get this output

varplus: [0] = PATH
varplus: [1] =  "asd
varplus: [0] = PATH
varplus: [1] = ���
test: [0] = PATH
test: [1] =  "asd

So varplus holds the right strings before the function call, but after it breaks, while test holds them all the way. Which makes me thing that I'm losing the array somehow.

1

There are 1 best solutions below

3
ikegami On

C17 §6.5.2.5 ¶5 [...] If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

In simple terms, it has a similar duration as int i.

You are returning a pointer to this object. Dereferencing this pointer (as you do) is undefined behaviour.