2

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!!!

Arik K
  • 31
  • 3
  • 7
    Given `char *buffer`, what do you think `buffer[i]` is? – Andrew Henle Oct 15 '18 at 17:24
  • 2
    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 Oct 15 '18 at 17:37
  • 1
    @WhozCraig [True](https://stackoverflow.com/questions/52821836/in-c89-i-cant-seem-to-make-a-character-array-from-an-existing-one#comment92560965_52821836) 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 Oct 15 '18 at 17:43
  • 2
    @chux or do something brave like, call me crazy, *retain the count of strings* in something besides `i` or enumerating `envp` *again*. – WhozCraig Oct 15 '18 at 17:45

3 Answers3

4

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;
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
dbush
  • 205,898
  • 23
  • 218
  • 273
1

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.

Kon
  • 4,023
  • 4
  • 24
  • 38
0

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;
}
Arik K
  • 31
  • 3