Stelios
Stelios

Reputation: 271

How to pass the address of a double pointer to another double pointer

How can I pass the address of a double pointer to an other? I have this code and it's working correctly only if i set the commented line. Why the size is different?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
    char *s1[]={"this","is","a","test"};
    char **s2;
    int i;
    s2=malloc(sizeof(s1)*sizeof(char *));
    s2=s1;
    for(i=0;i<sizeof(s2)/sizeof(char *);i++)//for(i=0;i<sizeof(s1)/sizeof(char *);i++)
        printf("%s",*(s2+i));
    return 0;
}

Upvotes: 0

Views: 1952

Answers (4)

Nik
Nik

Reputation: 695

sizeof(s1)... gives total no. of bytes..

what u are thinking cud be possibly implemented as follows:

s2=malloc(sizeof(s1)*sizeof(char *));

s2[0] = malloc(sizeof(s1[0])*sizeof(char))
.
.
.
.
n so on

Upvotes: 0

Jon Cage
Jon Cage

Reputation: 37490

sizeof(s1) gives the total number of bytes in the outer array i.e. the size of the four pointers to the string arrays. On my machine this gives 16 bytes (each pointer is 32 bit). Your declaration for s1 is eqivalent to doing:

char *s1[4]={"this","is","a","test"};

You can see those sizeof results for yourself:

printf("sizeof(char[4]) == %d\n", sizeof(char*[4])); // == 16
printf("sizeof(char**) == %d\n", sizeof(char**)); // == 4

Since s2 is a char** which is effectively a char* from point of view of the sizeof function, sizeof(s2) gives the size of a char* which on my machine is 4 bytes.

If you want to assign s2 to s1 and print it out try this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    char *s1[]={"this","is","a","teeeeeeeeeeest"};
    char **s2;

    s2 = s1;
    int numOfElementsInS1 = sizeof(s1)/sizeof(*s1);
    for(int i = 0; i < numOfElementsInS1; i++)
    {
        printf("s2[%d] = %s\n", i, s2[i]);
    }

    return 0;
}

...which should give:

s2[0] = this
s2[1] = is
s2[2] = a
s2[3] = teeeeeeeeeeest

If your goal here is to copy the contents of s1 then you'll need something like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    char *s1[]={"this","is","a","teeeeeeeeeeest"};
    char **s2;

    // Allocate memory for s2 and copy the array contents across
    int numOfElementsInS1 = sizeof(s1)/sizeof(*s1);
    s2 = (char**)malloc(sizeof(s1));
    for(int i = 0; i < numOfElementsInS1; i++)
    {
        size_t bytesInThisString = strlen(s1[i]) + 1; // + 1 for the string termination
        s2[i] = (char*)malloc(bytesInThisString);
        memcpy(s2[i], s1[i], bytesInThisString);
    }

    // Print out s2
    for(int i = 0; i < numOfElementsInS1; i++)
    {
        printf("s2[%d] = %s\n", i, s2[i]);
    }

    // Free up the memory
    for(int i = 0; i < numOfElementsInS1; i++)
    {
        free(s2[i]);
    }
    free(s2);

    return 0;
}

Upvotes: 0

Andomar
Andomar

Reputation: 238116

The commented line uses sizeof(char*[4]), which presumably is four times the size of sizeof(char**) on the uncommented line.

Upvotes: 2

Lindydancer
Lindydancer

Reputation: 26104

When using the sizeof operator, you will get the size of the array (in bytes). However, when applied to a pointer, you will get the size of the pointer, not the data it points to.

In C, there is no way to find this information, so you must manage this manually, for example by having a size variable or (as you already have done) use the size of s1 (which will only work as long as s1 is an array).

Upvotes: 1

Related Questions