Reputation: 103
I am not able to understand the difference between strcpy function and the method of equating the addresses of the strings using a pointer.The code given below would make my issue more clear. Any help would be appreciated.
//code to take input of strings in an array of pointers
#include <stdio.h>
#include <strings.h>
int main()
{
//suppose the array of pointers is of 10 elements
char *strings[10],string[50],*p;
int length;
//proper method to take inputs:
for(i=0;i<10;i++)
{
scanf(" %49[^\n]",string);
length = strlen(string);
p = (char *)malloc(length+1);
strcpy(p,string);//why use strcpy here instead of p = string
strings[i] = p; //why use this long way instead of writing directly strcpy(strings[i],string) by first defining malloc for strings[i]
}
return 0;
}
Upvotes: 1
Views: 1469
Reputation: 20141
A short introduction into the magic of pointers:
char *strings[10],string[50],*p;
These are three variables with distinct types:
char *strings[10]; // an array of 10 pointers to char
char string[50]; // an array of 50 char
char *p; // a pointer to char
Then the followin is done (10 times):
scanf(" %49[^\n]",string);
Read C string from input and store it into string
considering that a 0 terminator must fit in also.
length = strlen(string);
Count non-0 characters until 0 terminator is found and store in length
.
p = (char *)malloc(length+1);
Allocate memory on heap with length + 1 (for 0 terminator) and store address of that memory in p
. (malloc()
might fail. A check if (p != NULL)
wouldn't hurt.)
strcpy(p,string);//why use strcpy here instead of p = string
Copy C string in string
to memory pointed in p
. strcpy()
copies until (inclusive) 0 terminator is found in source.
strings[i] = p;
Assign p
(the pointer to memory) to strings[i]
. (After assignment strings[i]
points to the same memory than p
. The assignment is a pointer assignment but not the assignment of the value to which is pointed.)
Why strcpy(p,string);
instead of p = string
:
The latter would assign address of string
(the local variable, probably stored on stack) to p
.
The address of allocated memory (with malloc()
) would have been lost. (This introduces a memory leak - memory in heap which cannot be addressed by any pointer in code.)
p
would now point to the local variable in string
(for every iteration in for
loop). Hence afterwards, all entries of strings[10]
would point to string
finally.
Upvotes: 1
Reputation: 2556
strcpy
copies a particular string into allocated memory. Assigning pointers doesn't actually copy the string, just sets the second pointer variable to the same value as the first.
strcpy(char *destination, char *source);
copies from source to destination until the function finds '\0'. This function is not secure and should not be used - try strncpy
or strlcpy
instead. You can find useful information about these two functions at https://linux.die.net/man/3/strncpy - check where your code is going to run in order to help you choose the best option.
In your code block you have this declaration
char *strings[10],string[50],*p;
This declares three pointers, but they are quite different. *p
is an ordinary pointer, and must have space allocated for it (via malloc
) before you can use it. string[50]
is also a pointer, but of length 50 (characters, usually 1 byte) - and it's allocated on the function stack directly so you can use it right away (though the very first use of it should be to zero out the memory unless you've used a zeroing allocator like Solaris' calloc
. Finally, *strings[10]
is a double pointer - you have allocated an array of 10 pointers, each element of which (strings[1]
, strings[9]
etc) must be allocated for before use.
The only one of those which you can assign to immediately is string
, because the space is already allocated. Each of those pointers can be addressed via subscripts - but in each case you must ensure that you do not walk off the end otherwise you'll incur a SIGSEGV "segmentation violation" and your program will crash. Or at least, it should, but you might instead get merely weird results.
Finally, pointers allocated to must be freed manually otherwise you'll have memory leaks. Items allocated on the stack (string
) do not need to be freed because the compiler handles that for you when the function ends.
Upvotes: 1
Reputation: 12732
char *strings[10]---- --------->1.
strcpy(strings[i],string) ----->2.
strings[i] = string ----------->3.
p = (char *)malloc(length+1); -|
strcpy(p,string); |-> 4.
strings[i] = p;----------------|
strings
is an array of pointers, each pointer must point to valid memory.Will lead undefined behavior since
strings[i]
is not pointing to valid memory.- Works but every pointer of
strings
will point to same location thus each will have same contents.- Thus create the new memory first, copy the contents to it and assign that memory to
strings[i]
Upvotes: 1