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
?
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
?
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?
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.
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.