2
votes

So my code breaks down at buffer[i] = envp[i].

I want to create a char**buffer of the environment variables, and make them lower case (didn't add the putc(tolower()) yet loop). But when I just try to make buffer[i] = envp[i], the compiler returns me this error:

error: assignment makes integer from pointer without a cast [-Wint-conversion] buffer[i] = envp[i]; ^

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=] printf("%s\n", buffer[i]); ~^ ~~~~~~~~~ %d

int main(int argc, char *argv[], char * envp[])
{
    int i = 0;

    char *buffer = NULL;

    while(envp[i])
    {
        i++;
    }

    buffer = (char *)malloc(i * 8);


    for (i = 0; envp[i] != 0 ; i++)
    {
        buffer[i] = envp[i];
        printf("%s\n", envp[i]);
        printf("%s\n", buffer[i]);
    }

    return 0;

}

Please help, I've been breaking my head here :( . Thanks so much!!!

3
Given char *buffer, what do you think buffer[i] is?Andrew Henle
Even if buffer is changed to be a sequence of char * rather than char as it is now, nothing is being copied except the pointers from evp[]. In short, it's shallow copying. Where originally you had one set of pointers pointing to those strings (in evp[]), now you would have two (in evp[] and buffer[]). I somewhat doubt that accomplishes much for you.WhozCraig
@WhozCraig True about duplication of arrays. Note a repaired buffer[] still relies on envp[] to know how many are valid in buffer[]. I'd expect buffer[] to be 1 element larger for a NULL.chux - Reinstate Monica
@chux or do something brave like, call me crazy, retain the count of strings in something besides i or enumerating envp again.WhozCraig

3 Answers

4
votes

buffer is not the correct type to hold an array of strings. It should be defined as:

char **buffer;

Also, you should malloc as follows:

buffer = malloc(i * sizeof(*buffer));

Use sizeof(*buffer) explicitly instead of the magic number 8, as a pointer is not guaranteed to be 8 bytes. This is also prefered to sizeof(char *) as it does not depend on the type of buffer Also, don't cast the return value of malloc.

Since env is terminated by a NULL pointer, you'll want to do the same with buffer. You should also copy the strings with strdup instead of just copying the pointers so you can work on a separate copy:

char **buffer = malloc((i+1) * sizeof(*buffer));

for (i = 0; envp[i] != 0 ; i++)
{
    buffer[i] = strdup(envp[i]);
    printf("%s\n", envp[i]);
    printf("%s\n", buffer[i]);
}
buffer[i] = NULL;
1
votes

char * envp[] is an array of pointers to characters, not array of characters. And a pointer (envp[i]) is an integer. When you try to assign it to buffer[i] (which is a character), you get your warning.

0
votes

Thanks guys for the feedback, I was able to fix my function after the comments here. Cheers for the help!!!

char **lower_env(int argc, char *argv[], char * envp[])
{
    int i = 0;
    int k = 0;
    int length = 0; /*Going to dictate lengths later on*/
/*creating the double buffer*/
char **buffer;

/* Finding the amount of elements in the environment array*/
while (envp[i])
{
    i++;
}

/* Allocate the memory for the Buffer to hold that amount of elements*/
buffer = calloc(i+1, (sizeof(char*)));


for (i = 0; envp[i] ; i++)
{

    length = strlen(envp[i]); /*Finding the length of each array pointed
                                at by the original environment array*/

    buffer[i] = calloc(length+1 , sizeof(char)); /*Allocating that memory space
                                                        within our buffer array*/


    /*copying over the arrays in lowercase pointed at by the env array to a new memory location
        pointed at by our new buffer array*/
    for (k = 0; k != length; k++)
    {
        buffer[i][k] = tolower (envp[i][k]);
    }
}

return buffer;
}