-1

Here is my code.

int main()
{
struct emp
{
    char *n;
    int age;
};
struct emp e1 = {"Dravid", 23};
struct emp e2 = e1;
strupr(e2.n);
printf("%s\n", e1.n);
return 0;
}

Question 1: The answer as per the website is 'DRAVID' that is upper case. Howcome, are e2 and e1 same? i.e. if I do, e2.age++ then will this change be reflected in e1 too?

Question 2: If I change the strupr to strcpy I get seg fault? Why? i.e. If i change it to strcpy(e2.n,"hoho");.

Kraken
  • 23,393
  • 37
  • 102
  • 162
  • If you change strupr to strcpy you should get a compile error, because strcpy expects 2 arguments, not 1. – sashoalm Oct 24 '12 at 18:20
  • 2
    Also, calling `strupr()` is UB as well, it also tries to modify the string literal in-place. –  Oct 24 '12 at 18:21

6 Answers6

3

After you construct your two emps, this is what you have in memory:

e1.age  = 23
e1.name = 0x12345678 (Which is a pointer in memory to "Dravid")
e2.age  = 23
e2.name = 0x12345678 (Which is a pointer in memory to "Dravid")

Now notes, on what you're trying to do.

  1. Calling strupr(e1.name) is undefined behavior, because you're not allowed to modify string literals.
  2. Calling strcpy(e1.name, e2.name) is also undefined behavior, because strcpy requires that the two pointers passed to it refer to different pieces of memory. Also, its UB because you can't modify string literals.
  3. Calling strcpy(e1.name, "hiho") is also undefined behavior, because you can't modify string literals.
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • It is about `strcpy(e2.n,"hoho")`, not `strcpy(e1.name, e2.name)`. – glglgl Oct 24 '12 at 18:25
  • @glglgl: Thanks, that edit was apparently after I started responding. – Bill Lynch Oct 24 '12 at 18:26
  • @sharth but the website says that with strupr i will get DRAVID, how come? If that is also not defined behaviour? I am modifying the string there too? – Kraken Oct 24 '12 at 18:27
  • I can't comment on the contents of a website I don't know of. What I can say is that the code you have shown us is broken for the above reasons. – Bill Lynch Oct 24 '12 at 18:28
  • @sharth so as per you, if i use strupr, it is seg fault right? – Kraken Oct 24 '12 at 18:31
  • @Kraken: It's undefined behavior. A common side-effect of undefined behavior is a segmentation fault. – Bill Lynch Oct 24 '12 at 18:32
  • @sharth The OP stated the language is C. Unless the `const` specifier is used, strings are mutable in C and can be modified at will. (In truth, there is no such thing as a C 'string', only character arrays terminated by a null). A segmentation fault may occur if the allocated memory space is overrun by a copy operation. – Peter Gluck Oct 24 '12 at 18:49
  • @PeterGluck: 2011 C Standard. Section 6.4.5. Paragraph 7. __"It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined."__ This means that an implementation is allowed to store the data in Read Only memory, and that if a piece of code references the string literal "Foo" twice, both of those can refer to the same memory. [PDF of the C-2011 Standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf). – Bill Lynch Oct 24 '12 at 18:52
  • @PeterGluck, it is undefined behavior as it is up to the compiler vendor as to how to put literal strings. for some devices the literal strings may be put into a read only memory for instance. C is notoriously loose with the rules giving you lots of flexibility as well as lots of rope to hang yourself with. In some cases the compiler may aggregate strings so that the same text in multiple places points to the same address. – Richard Chambers Oct 24 '12 at 18:53
1

1) Assigning a structure does a memberwise copy. Since n is a pointer, the pointer address is copied so it points to the same string.

2) strcpy requires two arguments. Remember that e2.n is a pointer. You must allocate sufficient space to that pointer to hold the contents of the new string when calling strcpy. You are better off with strncpy():

int maxlen = 20;
e2.n = malloc(maxlen);
strncpy(e2.n, "Any length string here", maxlen - 1) /* only copies 19 bytes + terminating null */
Peter Gluck
  • 8,168
  • 1
  • 38
  • 37
1

When you copy a struct to another you copy all the values in the struct. For age you just copy the value, so you can change it and they will differ.

For n you are copying the address of the string so when you change one of the strings you also change the other.

And, as H2CO3 pointed out, you can't modify string literals which is what you attempt to do when using strcpy.

pedrosorio
  • 870
  • 5
  • 8
1

Q1. The char * n stores the address, which is copied, so if you change the value at the both will be reflected.

Q2. strcpy() needs 2 parameters, can you show what did you code.

AnandVeeramani
  • 1,526
  • 9
  • 15
0

C, unlike Java, uses different memory areas for different variables. So when you assign one struct to another, it does what is basically a shallow copy of one area to another. By shallow copy what I mean is that any pointers are not followed through to make clones of those so any pointers will point to the same place. It is just a copy of one memory area to another.

To say struct emp e2 = e1; is the same thing as to say memcpy (&e2, &e1, sizeof(struct emp));

This in turn means that if you assign a struct to another struct variable and then modify the data in the other struct variable, the first struct variable is not modified.

So in C each variable is a different memory location where as with Java and some other languages you are working with variable references and the variable names are just containers for the variable reference (except for built in primitives like int).

You have a bit of a possible problem with your code in that you are using a constant string. It is not good to modify a constant string as you are doing with strupr() because you do not know how the memory is allocated or where it is allocated. So with doing a strupr() you are basically getting lucky.

See this about difference between a deep copy and a shallow copy.

Community
  • 1
  • 1
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
-1

They should not be the same after the call to strupr (but it's not safe or proper to modify a string literal anyway). And no, a change to e2 will not be reflected in e1 because the assignment will copy the object by value.

As for changing the strupr call to strcpy, strcpy takes two arguments, so just changing it will cause a compilation error. If you add e1.n as the second argument, it will crash because e2.n hasn't been initialized to point to any memory.

user1610015
  • 6,561
  • 2
  • 15
  • 18
  • "They should not be the same after the call to strupr" - well, they should, since they point to the same (changed) memory location. –  Oct 24 '12 at 18:25
  • 1
    please remove your answer then. –  Oct 24 '12 at 18:49