0

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.

Chris
  • 26,361
  • 5
  • 21
  • 42
  • Does this answer your question? [Lifetime of referenced compound array literals](https://stackoverflow.com/questions/14955194/lifetime-of-referenced-compound-array-literals) - or any of these? https://stackoverflow.com/search?q=compound+literal+lifetime – Ted Lyngmo Jul 25 '23 at 05:54

1 Answers1

1

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.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Shouldnt the computer prevent me from doing so? You can't return a local variable, so why does the computer allows me to return a pointer that I can't dereference? – Rubens Freire Jul 25 '23 at 05:52
  • 1
    @RubensFreire: Because you are programming in C and not Rust :) Both cases are [undefined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). No, the computer will not necessarily prevent you, nor will it guarantee any particular kind of failure if you do so. – Nate Eldredge Jul 25 '23 at 05:57
  • 1
    @RubensFreire Most compilers will however be able to help you by emitting warnings if you ask them to. – Ted Lyngmo Jul 25 '23 at 05:59
  • All Right makes sense. Thank you. – Rubens Freire Jul 25 '23 at 06:01