1

Consider char *a[] = {"abc", "xyz", "def"};

Deep copy char *a[] to char **b.

Can someone say what is deep copy? And how much memory we need assign to b?

user1280282
  • 303
  • 4
  • 12
  • Your first question is answered [here](http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) – Krishnabhadra Apr 24 '13 at 08:37
  • 5
    this is your homework right? deep copy means you should copy the values, not just the pointers, b needs 12 bytes – x4rf41 Apr 24 '13 at 08:37
  • @x4rf41, on platforms where a `char` is one byte :) And that's without taking the pointers into account :) – StoryTeller - Unslander Monica Apr 24 '13 at 08:39
  • 1
    i just counted the pointers, which i assume are 4 bytes, logically the strings themselves are 4 bytes each, but can be anywhere and arent bound to the array – x4rf41 Apr 24 '13 at 08:40
  • 1
    1. allocate array of char*[3]. 2. for each i-th pointer in that array make allocation of strlen(a[i]+1) and copy a[i] into new array. Another way - to use strdup, which will do malloc/memcpy for you. – Eddy_Em Apr 24 '13 at 08:42
  • @x4rf41, the pointers don't have to 4 bytes either. It's best to describe such things in terms `sizeof`, IMHO. – StoryTeller - Unslander Monica Apr 24 '13 at 08:43
  • I have so much to learn!! How on earth do you convert `an array of pointers to char` to `a pointer to a character pointer`?How can we convert an array of something to a single pointer variable?Can anyone explain? – Rüppell's Vulture Apr 24 '13 at 08:49
  • Is the question properly phrased?How can we convert an `array of pointers to characters` to `a pointer to a character pointer`? – Rüppell's Vulture Apr 24 '13 at 08:52
  • 3
    StoryTeller, `char` by definition stores 1 byte. See for example [Are there machines, where sizeof(char) != 1?](http://stackoverflow.com/q/2215445) – Emil Vikström Apr 24 '13 at 09:04

3 Answers3

1
char *a[n];

Is an array of n pointers-to-char. Each element of the array is contiguous in memory. The size in memory required is

sizeof(char *) * n

I've used the sizeof() operator here... you could assume 4 bytes for a pointer but this might not be safe... this depends on your hardware.

char **b

Is slightly different. This is a pointer to a point-to-char. **b has not allocated the array of pointers. First allocate the array...

char **b = malloc( sizeof(char *) * n);

EDIT: Thank you to interjay for pointing out my mistake... example below now uses strdup() to allocate the memory for each b[i]

**b points to the start of an array of n pointers. For each pointer in that array you could so do b[0] = a[0] for shallow copies

This is a shallow copy because b[0] will point to the same memory that a[0] points to. Thus changing the contents b[0] will change the contents of a[0].

A deep copy would imply that you have two totally independent entities... so changing the contents b[0] would not result in a change to the contents of a[0]. This means that for each b[i] you need to allocate new memory and copy the string from a[i] into that new block.

To deep copy:

char *a[n];
// ...intialise array a....
char **b = malloc( sizeof(char *) * n); // allocate array of pointers
if( b )
{
   int i = 0;
   for(; i < n; ++i)
        b[i] = (char *)strdup(a[i]); // allocate memory for new string and copy string
}
else
   printf("You ran out of memory!\n");

As an asside... You've used constant strings so you shouldn't technically modify them...

char *xxx = "String";
char yyy[] = "String";

You can safely modify the contents of yyy. Normally you can modify the contents of xxx without any problem, but note, because the string memory is allocated at compile time, you could find that the compiler has, for example, placed it in read only memory.

EDIT: There seems to have been debate on whether to cast return from malloc (which I've been in the habit of doing, but it seems this was a bad habit!)... see Why do we need to cast what malloc returns?

Community
  • 1
  • 1
Jimbo
  • 4,352
  • 3
  • 27
  • 44
  • You need to allocate memory for each `b[i]`. – interjay Apr 24 '13 at 09:01
  • malloc() returns void*, you need to cast it – Khaled.K Apr 24 '13 at 09:51
  • 1
    @KhaledAKhunaifer That is [incorrect](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – interjay Apr 24 '13 at 10:39
  • @interjay: Hi interjay, why's that? Wouldn't I get a compiler warning or is the implicit cast from void* to type* always assumed as being okay by the compiler? – Jimbo Apr 24 '13 at 11:07
  • @Khaled & interjay: Ooh... i've learnt something, thanks interjay :) Found ans to my question here: http://stackoverflow.com/questions/1634153/why-do-we-need-to-typecast-what-malloc-returns – Jimbo Apr 24 '13 at 11:12
  • Why the recent downvote? Spotted something that could be improved? – Jimbo Jun 25 '13 at 13:12
1

Walking on the a array, for eah a[i] request space to alloc it by using one of *alloc() family functions and put the result in the respective b[i]. The b pointers itself shall be a pointer with enough space for hold the number of string in a as pointers. Compute with something like this:

    int bsize = (sizeof(a)/sizeof(a[0])) * sizeof(char*);
    char **b = malloc(bsize);
    int i,len;
    /* if(b == NULL) /* error: no memory */
    for(i = 0,len = sizeof(a)/sizeof(a[0]); i < len; i++) {
        char *tmp = malloc(strlen(a[i])+1);
        if(tmp == NULL) /* error: no memory */
        strcpy(tmp, a[i]);
       b[i] = tmp;
    }

Note that you need to or hold the size of b array in memory either put a NULL at end of array.

Jack
  • 16,276
  • 55
  • 159
  • 284
  • The downvote could be due to using `sizeof(int)` instead of `sizeof (char *)` to compute `bsize`, or the undefined variable `tmp`. – Armali Aug 30 '16 at 09:31
-1

You can just do

b=a

This will assign base address of array of pointers *a[3] to b.

Now you can access strings using b

for example string 1 can be accessed by *(b+0)  gives address of string 1
            string 2 "                " *(b+1)  "              " string 2
            string 3 "                " *(b+2)  "              " string 3

Since you are assigning array of pointers to pointer to a pointer you are already assigning memory to b Hence you do not need to use malloc.

Only when you are assigning some data to a pointer at run time and you have not assigned memory to pointer in your program then only use malloc.

Mohit Shah
  • 843
  • 1
  • 6
  • 20