Thread: char pointer error

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    46

    char pointer error

    Hi,

    I'm pretty new to C programming, so bear with me if this has a simple answer.
    I have an error that seems very strange to me. The following code when run produces an error and crashes.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ()
    {
    	int i;
    	char *str;
    	
    	gets(str);
    	
    	return 0;
    }
    The strange thing is that if i get rid of the
    Code:
    int i;
    or if i put the
    Code:
    int i;
    after the
    Code:
    char *str;
    there is no error. Also, the
    Code:
    gets(str);
    can be replaced by an analogous scanf function and the same error results. The same error also results when using a double, float, char etc... instead of an int.
    However, when I declare str as
    Code:
    char str[4];
    for example, there is no error.
    Any ideas?

    Thanks for your help.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > The following code when run produces an error and crashes.
    Consider yourself lucky then.
    For some people, it runs perfectly (it's still wrong though), but because it "works", they think they're doing something right.

    > char *str;
    OK, this is a pointer - but where is it pointing?
    You didn't say str = something; so it's just going to be some uninitialised (random) value. Basically, you're about to try and overwrite someone elses (or some non-existant) memory.

    > gets(str);
    oops, where did your input go?
    Right over memory you didn't own.
    Also, gets() is the world's most evil function - read this FAQ
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    > The strange thing is that if i get rid of the ... or if i put the ... after the ... there is no error.
    So you get a different random location go mess about with - still doesn't make it any more correct.

    > can be replaced by an analogous scanf function and the same error results.
    Writing to where uninitialised pointers point to is always bad, it doesn't matter which function you use to do it.

    > However, when I declare str as char str[4]; for example, there is no error.
    Well that sets aside 4 chars which you can modify.
    But that still doesn't make it correct to use gets() (See the FAQ)
    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.

  3. #3
    Registered User
    Join Date
    Feb 2005
    Posts
    46
    Ok so lemme see if I got this.

    When I write
    Code:
    char *str;
    the pointer named str simply contains whatever address happened to be lying around in that memory location where str was created. And therefore, when I try to gets() some characters starting at that address, it will be stored beginning at whatever that address in str happened to be (which might be an invalid location). Is this right so far?

    Ok so, if instead I write
    Code:
    char *str = "abcdefg";
    this doesn't seem to help. This is another thing i'm not really clear on. Does the string "abcdefg" just get stored in some random location, and then str points to that location?

    If instead I write
    Code:
    char c;
    char *str = &c;
    then everything seems to work fine. However, I get the feeling that this is not good because if more than one character is stored starting at &c then it might start overwriting some other memory that it's not supposed to.

    How, then, can I go about storing a string? Is the only way to create a sufficiently large char array?

    Thanks for your help.
    Last edited by Marksman; 02-26-2005 at 03:18 PM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Is this right so far?
    Yes.

    > Does the string "abcdefg" just get stored in some random location, and then str points to that location?
    Not an entirely random location - the compiler creates some space, stores the string in that space, then points str to the start of that space.
    printf( "%s\n", str );
    prints the obvious thing.

    > char *str = &c;
    As you said, this is only good for storing one character, and trying to store more will overwrite something you shouldn't.

    > How, then, can I go about storing a string?
    Code:
    char buff[BUFSIZ];  /* BUFSIZ is a constant in stdio.h */
    fgets( buff, BUFSIZ, stdin );
    > Is the only way to create a sufficiently large char array?
    There is no standard "get a string of any length" call, but you can call fgets() in a loop to get a large amount of input over many calls. Combined with memory allocation you can then read as much input as you've got memory to store it.
    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.

  5. #5
    Registered User
    Join Date
    Feb 2005
    Posts
    46
    Ok one last question. In the following
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main (void)
    {
    	int i;
    	char *str = "xyzabc";
    	
    	gets(str);
    	
    	return 0;
    }
    I still get an error.
    Now when the computer sets aside memory for the string "xyzabc", I assume it will only put it in valid memory, memory that isn't already used, and isn't invalid etc.. And str now points to the first location of the 'x'.
    So why does this still produce an error after inputting to gets(), even when inputting a string shorter than the initialized one?

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>char *str = "xyzabc";
    This is a pointer to a string literal; you're not allowed to write to string literals. If you want storage, use an array (str[SIZE]) or dynamic memory allocation (malloc()).
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    And stop using gets()
    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.

  8. #8
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  9. #9
    Registered User
    Join Date
    Feb 2005
    Posts
    46
    Ok, so the reason that last one didn't work is because I am not allowed to overwrite string literals stored in memory?


    So statements like
    Code:
    char *str = "abc";
    str = "qwerty";
    str = "asdf";
    are perfectly fine (because new memory locations for each string are created), whereas statements like
    Code:
    char *str = "abc";
    fgets(str, 4, stdin);
    are WRONG (because I am trying to overwrite a string literal) and should never be used?


    Hopefully I've got this... Thanks for the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Making C DLL using MSVC++ 2005
    By chico1st in forum C Programming
    Replies: 26
    Last Post: 05-28-2008, 01:17 PM
  2. more then 100errors in header
    By hallo007 in forum Windows Programming
    Replies: 20
    Last Post: 05-13-2007, 08:26 AM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Why wont my function exit correctly?
    By LightsOut06 in forum C Programming
    Replies: 2
    Last Post: 10-09-2005, 09:23 PM
  5. Stupid compiler errors
    By ChrisEacrett in forum C++ Programming
    Replies: 9
    Last Post: 11-30-2003, 05:44 PM