2

I have two dynamically allocated arrays. c

char **a = (char**)malloc(sizeof(char*) * 5));
char **b = (char**)malloc(sizeof(char*) * 5));

for (int i = 0; i < 7, i++) {
  a[i] = (char*)malloc(sizeof(char)*7);
  b[i] = (char*)malloc(sizeof(char)*7);
}

If a[0] was "hello\0" and I wanted to copy a[0] to b[0], would strcpy and pointer assignment be the same thing? For example:

  1. strcpy(b[0], a[0])
  2. b[0] = a[0]

Would these both do the same exact thing?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Kevin Cheng
  • 39
  • 1
  • 6
  • 4
    [Don't cast the result of malloc (and friends)](http://stackoverflow.com/q/605845). Also, writing `sizeof(char)` is a bad idea, as it's guaranteed to be 1: How many byte is a byte big? – Deduplicator Sep 29 '14 at 09:26
  • 1
    Note that your code is broken in various ways, e.g. you only allocate five rows and you try to assign seven + your for loop syntax is wrong. – Paul R Sep 29 '14 at 09:31
  • do accept the answer that solved your problem :) – nightlytrails Sep 29 '14 at 10:18

4 Answers4

3

NO. Both are not same. In this case, strcpy(b[0], a[0]) is correct way to copy the string pointed by a[0] to b[0].

In case of b[0] = a[0], memory allocated to b[0] will lost and it will cause memory leak. Now freeing both of a[0] and b[0] will invoke undefined behavior. This is because both of them are pointing to same memory location and you are freeing same allocated memory twice.


NOTE: It should be noted that, as Matt McNabb pointed in his comment, memory leak does not invokes undefined behavior.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
1

Understand that a[0] and b[0] in this case are themselves arrays (or pointers to characters arrays, to be more precise)

strcpy() would traverse through each individual element of the character array which a[0] points to. While the assignment b[0] = a[0] will just make b[0] point where a[0] is pointing, resulting in memory leak (the memory to which b[0] was pointing cannot be free'd).

Visualize the state of affairs using a simple figure like this -

     +---+ -->  +------+          +---+---+---+---+---+----+
     | a |      | a[0] | ------>  |'H'|'E'|'L'|'L'|'O'|'\0'| 
     +---+      +------+          +---+---+---+---+---+----+
                | a[1] |
                +------+
                | ...  |
                +------+    
                | a[n] |
                +------+                                    
nightlytrails
  • 2,448
  • 3
  • 22
  • 33
  • Thanks alot! Really appreciate your time for drawing this. Can you please confirm what I commented below? I think I have it right. I just want to make sure I'm not mislearning concepts :) – Kevin Cheng Sep 29 '14 at 10:00
0

They are different. In strcpy() case you are copying the characters, in the assignment case you adjust the pointer to point to the same array.

 a[0] -> allocated memory containing "hello"
 b[0] -> allocated memory not yet initialised

After b[0] = a[0]

both now point to same memory

 a[0] -> allocated memeory containing "hello"
 b[0] ---^ 

and worse nothing now points to b[0]'s

 allocated memory not yet initialised

so you can never free it; memory leak.

djna
  • 54,992
  • 14
  • 74
  • 117
  • 1
    do you mean b[0] = a[0]? – Kevin Cheng Sep 29 '14 at 09:34
  • so what you're saying is, the original block of char i malloc'd for each b[i] will never be freed because b[i] points to a[i]. Basically i can never free each original char byte I malloc'd. Right? Thats essentially what I got by drawing it out. – Kevin Cheng Sep 29 '14 at 09:44
  • also, for the function free(), this function will free everything a pointer points to but not the actual pointer variable itself right? so if i were to do free(b[i]) it would free the individual char's I had malloced for b[i] but it wouldn't free b[i]. To free b[i] I would have to free b correct? (Does this mean I can only free all malloc'd memory at one time? For example, I wouldnt be able to free b[1] to b[4] only instead of freeing the entire b array? Thanks so much! – Kevin Cheng Sep 29 '14 at 09:46
  • `I wouldn't be able to free b[1] to b[4] only instead of freeing the entire b array?` Correct, you can't free them individually. There is no syntax for that. – nightlytrails Sep 29 '14 at 10:06
  • `"for the function free(), this function will free everything a pointer points to but not the actual pointer variable itself right?"` True. You can free() only what you malloc'd. – nightlytrails Sep 29 '14 at 10:06
  • `To free b[i] I would have to free b correct?`. That's also correct in this case. – nightlytrails Sep 29 '14 at 10:07
0

In this particular case they are not equivalent. If to assign a[0] to b[0] then there will be a memory leak or the same memory can be deleted twice when the arrays will be deleted.

So the correct approach is to use function strcpy.

Take into account that there is a typo in your example. Instead of

for (int i = 0; i < 7, i++) {
  a[i] = (char*)malloc(sizeof(char)*7);
  b[i] = (char*)malloc(sizeof(char)*7);
}

there shall be

for (int i = 0; i < 5, i++) {
  a[i] = (char*)malloc(sizeof(char)*7);
  b[i] = (char*)malloc(sizeof(char)*7);
}

However there are situations when it is much simpler to use pointer assignments. Consider task of swapping of two rows of the "same" dynamically allocated array. For example let's assume that we want to swap a[0] and a[4]. We could do the task the following way using strcpy

char *tmp = malloc( 7 * sizeof( char ) );

strcpy( tmp, a[0] );
strcpy( a[0], a[4] );
strcpy( a[4[, tmp );

free( tmp );

However it will be much simpler to swap only pointers:)

char *tmp = a[0];
a[0] = a[4];
a[4] = tmp;

There is no any need to alloocate additionally memory and then to free it.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Okay so when I do swapping in an array, I could just use pointer assignment? I did that to swap columns of a 2D array for a previous program and it worked fine. This is why I am asking the difference in this question. (So i can basically do this only when I'm not allocating memory right?) – Kevin Cheng Sep 29 '14 at 09:50
  • @Kevin Cheng You are write. You simply exchange values of the pointers. The memory itself is not touched. – Vlad from Moscow Sep 29 '14 at 09:53