Sukrit Kapil
Sukrit Kapil

Reputation: 103

What is the difference between using strcpy and equating the addresses of strings?

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

Answers (3)

Scheff&#39;s Cat
Scheff&#39;s Cat

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.

  1. 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.)

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

James McPherson
James McPherson

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

kiran Biradar
kiran Biradar

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;----------------|
  1. strings is an array of pointers, each pointer must point to valid memory.

  2. Will lead undefined behavior since strings[i] is not pointing to valid memory.

  3. Works but every pointer of strings will point to same location thus each will have same contents.
  4. Thus create the new memory first, copy the contents to it and assign that memory to strings[i]

Upvotes: 1

Related Questions