-2

This is the program working well for input: "problem"

but stops for: "this is the problem,this is the problem,this is the problem"

Why?

#include <stdio.h>

int main()
{
    char *p;
    gets(p);
    puts(p);
    return 0;
}

Is there any memory protection issue?

yulian
  • 1,601
  • 3
  • 21
  • 49

2 Answers2

6

You are missing to allocate memory, to read the data into using gets(), as char * p is just a pointer, pointing to a random address.

This provoke undefined behaviour. Anything could happen, even when read in only 1 character.

The fact, that the program does not crash for less then 26 characters is just bad luck.

You can provide memory by for example changing

char * p;

to be

char str[42] = {0}; /* = {0} initializes the array to all `0`s. */
char * p = str;

As per urzeit's comment: This makes p point to an array of 42 characters, which itself is capabale to hold a so called "string" of 41 characters. The 42nd character is resevered to hold the 0-terminator, that indicates the "string"'s end.


Note: gets() is evil, as the programmer has no possibility to tell the function how much characters the buffer passed to gets() is capabale to hold. Use fgets() instead.


Btw: int main(void) ought to return an int.

alk
  • 69,737
  • 10
  • 105
  • 255
  • 1
    Additional information: In this example strings up to a length of 41 (plus the 0-char terminating the string) can be stored in the memory address p. If the string is longer, this will still be undefined behaviour. – urzeit Sep 01 '13 at 07:09
  • Technically `main()` doesn't *have* to explicitly return, but I agree with you that it *ought* to. +1 for "bad luck" that it "does not crash". – Crowman Sep 01 '13 at 07:12
  • main() have to return explicitily. if you not explicitly return int, it will return the last function call return : here, it's puts returned value – 0xBAADF00D Sep 01 '13 at 07:14
  • 2
    @0xBAADF00D: `main()` will return `0` implicitly if you don't provide it. It's the only function for which that is true. – Crowman Sep 01 '13 at 07:15
  • @ urzeit u are right ..char str[4]; char * p = str; can accept string having length 12..... – user2725368 Sep 01 '13 at 07:17
  • @PaulGriffiths, please check by your self. I'have tested this on Debian 7 with GCC 4.7. It's not new, since many year, gcc return the last value on the top os the stack if you not specidy return value on main() – 0xBAADF00D Sep 01 '13 at 07:17
  • 3
    @0xBAADF00D: Please check the C standard, your compiler is no authority on correct C. Section 5.1.2.2.3 clearly says that "reaching the `}` that terminates the `main` function returns a value of `0`". – Crowman Sep 01 '13 at 07:18
  • @PaulGriffiths anyway, this is a false debate. if the prototype requires INT: return an INT. In C99 "default int" has been removed – 0xBAADF00D Sep 01 '13 at 07:21
  • @0xBAADF00D: I just quoted from C11. You can read it yourself if you don't believe me. – Crowman Sep 01 '13 at 07:22
  • @PaulGriffiths How, i see, you use g++ to compile .c file (very very very bad practive) ? I 'have test with g++ main return 0, but if you use cc ou gcc, main return the last returned value... – 0xBAADF00D Sep 01 '13 at 07:24
  • @0xBAADF00D: I've already answered that. g++ is a C++ compiler, by the way. gcc correctly returns zero if you use it properly. – Crowman Sep 01 '13 at 07:24
  • @PaulGriffiths this question have "C" tags not "C++" – 0xBAADF00D Sep 01 '13 at 07:27
  • 2
    @0xBAADF00D this is the excerpt from C99 draft standard (WG14/N1256) Paul already told you about: **5.1.2.2.3 Program termination. If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0. [...]** – LorenzoDonati4Ukraine-OnStrike Sep 01 '13 at 08:03
  • @0xBAADF00D Use `gcc -std=c99` to compile according to the C99 standard. GCC's default is c89+extensions and is quite obsolete. It is kept because moving to C99 changes the behavior of some defined programs, and it is difficult to tell what old code would be broken, see for instance http://blog.frama-c.com/index.php?post/2012/01/20/Constants-quiz and http://blog.frama-c.com/index.php?post/2012/01/20/Constants-quiz-answers (but we are getting off-topic here). – Pascal Cuoq Sep 01 '13 at 10:04
3

The actual reality is that it's probably "working" for short strings because you're just overwriting your stack, which is memory your program owns, so it doesn't crash. However, this is not "working" by any reasonable definition of the word.

From a C language point of view, all you know is that it's just undefined behavior, it's bad, and you should fix it.

Crowman
  • 25,242
  • 5
  • 48
  • 56