-5

I Just came along a question and when i compiled and run it in CodeBlockes I got an error and i could not run it.

Here is the question.

What will be the output of the program ?

#include<stdio.h> 
#include<string.h>
int main(){
   int i, n;
   char *x="Alice";
   n = strlen(x);
   *x = x[n];
   for(i=0; i<=n; i++){
      printf("%s ", x);
      x++;
   }
   printf("\n", x);
   return 0;
}

A. Alice

B. ecilA

C. Alice lice ice ce e

D. lice ice ce e

  • 1
    Maybe the error you got wanted to tell you something... – glglgl May 15 '13 at 08:08
  • 4
    *"I got an error and i could not run it.*". **Always** include the error messages, even if they're cryptic to you. – Zeta May 15 '13 at 08:08
  • I know that errors mean something but that was not a compiler error. The error was from my OS(windows 7) and said that the program can not be run – ahmadreza mostajabi May 15 '13 at 08:13
  • then the problem is probably not in code. you need to elaborate the question including what commands you issued, what folders are you working in, and you might need to check file permissions. what you asked for it's not your real question – blue Jun 08 '13 at 12:18

5 Answers5

8

That code looks wrong. The line

*x = x[n];

tries to write to the string literal "Alice". String literals cannot be modified so this results in undefined behaviour. A crash (as I think you're seeing) is a valid and expected result here.

To answer your question, the output from the program is undefined. It is unlikely to give any of the results you suggest.

If you change the declaration of x to

char s[]="Alice";
char* x = s;

then

*x = x[n];

will replace the first character of x with its null terminator, meaning that the printf loop will output lice ice ce e (option D from your choices)

simonc
  • 41,632
  • 12
  • 85
  • 103
  • No, if you change the declaration of `x` to `char x[]`, then you will get a compiler error. –  May 15 '13 at 08:17
  • Thanks , but what is the difference between the array and the pointer here? Isn't array also a pointer? – ahmadreza mostajabi May 15 '13 at 08:18
  • 2
    @ahmadrezamostajabi No, [**they aren't at all.**](http://c-faq.com/aryptr/aryptr2.html) –  May 15 '13 at 08:18
  • @H2CO3 Thanks, I'd forgotten about the pointer arithmetic further down the function. Now corrected. – simonc May 15 '13 at 08:21
  • 1
    @ahmadreza mostajabi also have a look at this http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c – akristmann May 15 '13 at 08:47
5

What will be the output of the program?

Something indeterminate, it may even crash. On this line:

*x = x[n];

you're modifying a string literal, so your program invokes undefined behavior.

If you, however, modify the code so that the UB is gone (for example, you initialize an array with the string instead of using just a pointer to the string literal, and you get a pointer to the first element of that array), then it will be lice ice ce e.

  • @simonc Right, it does indeed, I've overlooked that... >. –  May 15 '13 at 08:15
  • "If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored." Passing more arguments to `printf` etc. than the format requires is harmless, only too few arguments (or arguments not matching the conversion specifier) invoke UB. – Daniel Fischer May 15 '13 at 11:26
  • @DanielFischer Thanks. I will then remove the erroneous part (I'm wondering though, in practice, how does it not cause stack corruption?) –  May 15 '13 at 11:31
  • @H2CO3 in C implementations, the caller is responsible for tidying up the stack, not the called function. The caller always knows how many arguments it put on the stack and thus knows how many to get rid of. – JeremyP May 15 '13 at 11:37
  • @JeremyP Good to know, and seems reasonable, indeed. (Now I'll have to play around with my compiler...) –  May 15 '13 at 11:41
2
char *x="Alice";
n = strlen(x);
*x = x[n];

On most systems "Alice" will be store in read only memory and x will be set to point to it. When you do *x = x[n] you will be trying to change the value of that read only memory so your program will exit with an error at that point.

jcoder
  • 29,554
  • 19
  • 87
  • 130
  • You haven't mentioned the exact reason backed by the correct terminology - making assumptions about OP's environment is nice and may even be reasonable, but it's not correct. –  May 15 '13 at 08:20
2

Change:

char *x="Alice";

To

char str[] = "Alice";
char *x=str;

And you will get D

Valeri Atamaniouk
  • 5,125
  • 2
  • 16
  • 18
  • @Rüppell'sVulture No, it isn't. –  May 15 '13 at 08:19
  • @Rüppell'sVulture I allocate string on stack, instead of data segment – Valeri Atamaniouk May 15 '13 at 08:20
  • @H2CO3 Aren't we storing "Alice" somewhere in memory and passing a pointer to that string to `x`? – Rüppell's Vulture May 15 '13 at 08:21
  • @Rüppell'sVulture Because it permits one to modify the string literal causing UB - **just** what happened here. –  May 15 '13 at 08:21
  • @H2CO3 So you think we should use an array for that or `const char *x="Alice";` would be OK? – Rüppell's Vulture May 15 '13 at 08:22
  • 1
    @Rüppell'sVulture Yes, those both are conceptually better/correct. –  May 15 '13 at 08:23
  • @H2CO3 But `char *x="Alice";` is syntactically correct and OK if we are careful about not modifying the string,right? – Rüppell's Vulture May 15 '13 at 08:25
  • 1
    @Rüppell'sVulture Syntactically, yes, but not semantically. Under "correct", I mean "syntactically **and** semantically correct". See, if there was a program calculating prime numbers, and it compiled (it was syntactically correct) but it outputted non-primes (it was semantically wrong), would you call that program "correct", after all? –  May 15 '13 at 08:27
  • @H2CO3 So declaring an array is best for this? – Rüppell's Vulture May 15 '13 at 08:27
  • 1
    @Rüppell'sVulture And **you never can be careful enough.** If you rely on that "D'oh, I won't forget this I know, and I don't want to be safe so let's just fool the compiler", then one day you **will** forget it and your code **will break terribly.** –  May 15 '13 at 08:28
  • @Rüppell'sVulture "Best" - for what? If you want to modify it, then declare an array. If you want a read-only string constant, then a pointer to its first character is enough. –  May 15 '13 at 08:28
  • @H2CO3 So what is the semantically and syntactically correct declaration and initialization for a read-only string constant?give an example...Will `const char *ptr="Hello"` be correct? – Rüppell's Vulture May 15 '13 at 08:32
0

Short answer: Output will mostly be seg-fault.

Explaination: x points to a const string - "Alice". & you are trying to modify *x.

anishsane
  • 20,270
  • 5
  • 40
  • 73