#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    5
    Rep Power
    0

    Strange outcomes for simple code


    New to the forum and new to C programming!

    Why is this acting so weird??

    used quincy 2005 compiler on win7
    1.enter 1 to 3 characters it works correctly.
    2.enter 4 characters -the count is correct but it asks for another string.
    3. enter five or more characters -puts up the correct count but then I get "file1.exe has stopped working"

    with devccp compiler.
    tried two machines got same result.
    1. no matter the number of characters i enter I get "file1.exe has stopped working"

    Here it is File1.c
    #include<stdio.h>
    #include<conio.h>
    int main()
    {
    char *str;
    int count = 0,i;
    printf("\nEnter the String: ");
    gets(str);
    for(i=0;str[i]!='\0';i++)
    {
    count++;
    }
    printf("\nThe length of the string is %d.",count);
    getch();
    }
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    1. Use code tags:
    Code:
    #include<stdio.h>
    #include<conio.h>
    int main()
    {
        char *str;
        int count = 0,i;
        printf("\nEnter the String: ");
        gets(str);
        for(i=0;str[i]!='\0';i++)
        {
            count++;
        }
        printf("\nThe length of the string is %d.",count);
        getch();
    }
    2. You are using an uninitialized pointer. Think of a pointer as a loaded gun. It has to be pointed at a proper target. You're just waving it around so that it could be pointed anywhere. You'd better count your toes because you just shot yourself in the foot.


    If you're going to use a char pointer in this example, then you need to malloc enough memory for it to point to. Either that or declare str as a char array of sufficient size. Sufficient size is the maximum number of characters it is expected to hold plus one more for the null-terminator, a byte containing zero that marks the end of the string. Get to know that null-terminator very well, because you need to; forgetting about the null-terminator will cause you all kinds of headaches in the future.

    As your code stands now, the address it's pointing to could literally be anywhere. Because the value it contains (and a pointer's value is a memory address) is garbage; ie, whatever value just happened to have been written to that memory location last either by your program or by whatever other process had just happened to have been loaded there. So what gets does is to overwrite something else's memory; this is called clobbering and can result in all kinds of weird inexplicable symptoms. But what's even more likely is that it points to a memory location outside your programs allotted memory space, which will trigger either an access exception (for trying to access memory that doesn't belong to you) or a segmentation fault (AKA "SEGFAULT"), which is pretty much the same thing. Or you could be trying to write to your own memory, but to memory that's been marked as read-only, which will also cause a crash.

    Allocate memory to that pointer or declare a char array. But if you should initialize it to NULL and try to write to that location, then you will be guaranteed to crash because that memory location belongs to the operating system and it will terminate you with extreme prejudice!
    Last edited by dwise1_aol; January 29th, 2013 at 08:21 PM.
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,378
    Rep Power
    1871
    Not to mention that gets() is the worlds most evil function and should never be used.
    read me
    Use fgets() and a char array.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  6. #4
  7. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,109
    Rep Power
    1802
    Just to get you started past this hurdle:

    Code:
        char str[80];
        int count = 0,i;
        printf("\nEnter the String: ");
        fgets( stdin, sizeof(str), str ) ;
    You created a pointer to nothing, where the entered data was stored was undefined, I am surprised that you could enter even one character without crashing, but anything could happen, including nothing!

    In the code above, str is an array not a pointer; it creates a space for 80 characters. I have also replaces your gets() call with fgets() because gets() does not provide a means to limit the number of characters entered - it is dangerous and you should forget it exists. fgets() will prevent the buffer from being overrun, which would also have undefined consequences and nothing good.


    Note that Quincy is not a compiler. It is an IDE. It is used with MinGW GNU GCC; that is your compiler.
    Last edited by clifford; January 30th, 2013 at 01:00 AM.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    5
    Rep Power
    0

    Thanks for you response


    After reading your response I did some more research and by only making a slight change the program works flawless. Thanks

    from char *str;
    to char *str = malloc( sizeof(*str) );
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    5
    Rep Power
    0

    Thanks for the information


    "You created a pointer to nothing, where the entered data was stored was undefined, I am surprised that you could enter even one character without crashing, but anything could happen, including nothing!"

    After reading your response and anothers I did some more research and by only making a slight change the program works flawless. Thanks

    from char *str;
    to char *str = malloc( sizeof(*str) );

    "Note that Quincy is not a compiler. It is an IDE. It is used with MinGW GNU GCC; that is your compiler."

    A quick search after this comment and now I have better knowledge of my software development environment. Thanks

    Also as being new to the forum I wanted to give credit where credit is due so under additional Options found after the reply to thread section I gave a 5 to the score for the thread, but I am thinking that's not the same as giving a great responder a numerical score for their helpful information. So unless that actually did it - could use the how to give credit where credit is due instructions. Thanks Again.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    5
    Rep Power
    0

    oh I missed the code tags comment - now I know -thanks


    1. Use code tags:

    googled code tags - oh OK

    Thanks again
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by jkitchens3
    After reading your response and anothers I did some more research and by only making a slight change the program works flawless. Thanks

    from char *str;
    to char *str = malloc( sizeof(*str) );
    No it doesn't work flawlessly. You're still clobbering memory that could be used for other data; it's just hidden from you.

    What is sizeof(*str)? One (1). You allocated one single byte of memory for a string. It initialized the pointer alright and that it is good. But if you store anything other than an empty string there, you will have buffer overflow. Since that's the only thing you've malloc'd in the heap, you won't notice that buffer overflow, but it's still there. If you do a lot of malloc'ing, say for a linked list or a tree structure, then if the string you read in is long enough it will overwrite parts of that other data and cause "inexplicable" weird things to happen.

    Rather, as I already told you (bold added):
    Originally Posted by DWise1_aol
    If you're going to use a char pointer in this example, then you need to malloc enough memory for it to point to. Either that or declare str as a char array of sufficient size. Sufficient size is the maximum number of characters it is expected to hold plus one more for the null-terminator, a byte containing zero that marks the end of the string.
    What's the maximum number of characters you're expecting to input. Having grown up so to speak in a 80-column punch-card environment, I'm used to declaring an input buffer to be 80 characters long, so that would make "sufficient size" 81. It'll be 81 characters, so we need to use sizeof(char), thus:
    Code:
        char *str = malloc( 81*sizeof(char) );
    Or you could still use (81*sizeof(*str)) if you really want to; it would be the same thing.

    Think about it and understand why that is necessary.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    5
    Rep Power
    0

    final for this thread


    I started off using LearnCOnline. Much evidence would support not to use this site. Many errors in his exp programs. At first I would just look at the problems and through the internet I could fix them so they would work for me.This thread is about the one that made me realize it was time to find another source. It seams that it is his opinion that by using pointers to character types that this allows the input not to need a preset amount of allocated memory. Now although his code would compile it would do all kinds of weird stuff usually ending in a file1.exe has stopped working. I believe that this was do to clobbering the memory (gathered from post in this thread) - anyway allocating sufficient memory for the input worked and thanks to all!

IMN logo majestic logo threadwatch logo seochat tools logo