Thread: Ptr crash.

  1. #1
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751

    Ptr crash.

    I'm crashing my code with this fragment here
    PHP Code:
    puts("tell me another name");
        
    char *name2=fgets(name2,MAX,stdin);
        
    int x strcspn(name2,"\n");
        
    name2[x] = '\0';/*know you can use the ternary operator and make this a compound statement */
        
    printf("Hey Again %s, Look i'm ndxing your ptr to name: name[MAX/2] = %d",name2,name2[MAX/2]); 
    any ideas why, i'm a little behind the weather this morning.
    x and MAX are already declared.
    Last edited by caroundw5h; 08-29-2004 at 08:39 AM.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >char *name2=fgets(name2,MAX,stdin);
    *Huge hint* What does name2 point to when you pass it to fgets?
    My best code is written with the delete key.

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Does name2 have enough allocated space?

    Also, your spelling of "indexing" is horribly mangled if that's what you were trying to spell.
    If you understand what you're doing, you're not learning anything.

  4. #4
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Quote Originally Posted by Prelude
    >char *name2=fgets(name2,MAX,stdin);
    *Huge hint* What does name2 point to when you pass it to fgets?
    See that's what I thought, its uninitialized, but isn't it initialized with the return value of fgets?

    see i had this code before
    PHP Code:
    /* name3.c -- reads a name using fgets() */
    #include <stdio.h>
    #define MAX 81
    #define num 5
    int main(void)
    {
    /*char *fgets(const char *, int n, FILE *STREAM). Easy enough fgets takes input from the
    speccified stream and stores it into the char * pointed to. it reads up to n. its only
    drawback is it also stores the newline in the char *. So this uses strcspn to find the index of
    '\n' and replace it with the '\0 char to terminate the string.*/

        //char name[MAX];

        
    printf("Hi, what's your name?\n");
        
    char *name=  fgets(nameMAXstdin);
        
    /*see this is valid because it is automaitally initialized
       to something intersting. interesting. oh the intricacies of C*/
       
    printf("name[4]= %c\n"name[num]);
        
    int ndx strcspn(name,"\n");
        
    name[ndx] ='\0';/* nice. this is an easy way to use the str char span function.
        since it returns an index of the string looking for get the index of the '\n' and replace
        it with the null char, thus terminating the string fegets arg will always be a string 
        anyway of char array, cause you ca't assign to a uninitalized ptr*/
        
        
    printf("Hey %s. My name is fgets. I normally put a \\n in your name?"name);
        
    getchar();
        return 
    0;
        
        
    /*another example with fgets this time using pointers*/
        

    and it works fine, so i was assuming oh you can initialize. Am i wrong.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  5. #5
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    You're only lucky that that's working. Basically what you're doing there is telling fgets() to store the user's input into some random memory location that most probably isn't allocated to you. Try changing name and name2 into char arrays of size MAX instead of pointers.
    If you understand what you're doing, you're not learning anything.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >but isn't it initialized with the return value of fgets?
    Initialized where? name2 doesn't point to memory in your address space, so you're writing to outer space. That usually results in a segmentation violation. The problem is that you haven't allocated space to the pointer before trying to write to it.

    >and it works fine
    Coincidence. It's just as broken as your first example.
    My best code is written with the delete key.

  7. #7
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Quote Originally Posted by itsme86
    You're only lucky that that's working. Basically what you're doing there is telling fgets() to store the user's input into some random memory location that most probably isn't allocated to you. Try changing name and name2 into char arrays of size MAX instead of pointers.
    Well thats what i did first
    Code:
    char name[MAX]
    and that worked fine so i decided to play around with it. Since fgets returns a char * of its first argument, i assigned name to.
    is there something else about pointers i have yet to learn, like garbege lying around in memory or something? I haven't started on dyanmic memory allocation yet, so i'm still a n00b.
    thanks


    Coincidence. It's just as broken as your first example.
    Now that's freaky. I swear no word of a lie the first code doesn't crash, but the second does.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  8. #8
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    You just need to realize that a pointer is just like any other variable except it's designed to hold the address of another variable or to some meaningful, useful memory location that you can use. So, if you define a variable int i; it's not guaranteed to start off holding the value 0. The compiler just says "ok, variable i is going to be at this memory location", whatever the this is that it picks. It doesn't alter the memory that's there, so whatever it used to contain it will still contain.

    When you define a pointer the same thing happens so your pointer contains some random value. When you use a dynamic memory allocation function like malloc(), it finds a free area of memory and allocates it to your program (simplified explanation, but it works) and then returns a pointer to that memory. The memory at that allocated location still contains random data, but at least it belongs to your program and you can use it however you want.

    So char *name = malloc(MAX); and char name[MAX]; are very nearly the same thing (I believe the FAQ contains information on the difference between a pointer and an array). But both can be used for your fgets() buffer.
    If you understand what you're doing, you're not learning anything.

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I swear no word of a lie the first code doesn't crash, but the second does.
    Undefined behavior has a way of doing that.

    >is there something else about pointers i have yet to learn
    Probably. But for now the lesson is that when you create a pointer variable, it doesn't point to memory that you can modify. This is true for local pointers that point to a random location as well as global pointers that are initialized to NULL. Before you can work with the memory that a pointer points to, you must assign it to memory that you own, like so (without dynamic allocation):
    Code:
    char buffer[MAX];
    char *name = fgets ( buffer, MAX, stdin );
    My best code is written with the delete key.

  10. #10
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Thanks for the replies. I'm aware of the random place in memory uninitialized ptrs point to. It just seemed when i wrote that second code and initilized it, it was a way to circumvent it. The fact that it didn't crash enocuraged me. That is kinda of scary that it fluked out like that. That means you have to be really careful an know what your coding when using pointers. I thought i had a good handle on them but seems there is still much to learn.
    in passing can you tell me why this works
    PHP Code:
    char line[80];
       
    puts("enter something else for fgets and i'll print it out");
       
    fgets(line,80,stdin);
       
    char *find strchr(line,'\n');
       if (
    find)*find='\0';
       
    puts(line); 
    strchr's prototype is char *strchr(const char *s, int c). so it returns a ptr to a char. intitilaizing find to its return value seems to work fine.

    also i was playing with the strtok funcion as well.
    PHP Code:
    char data[] = "C is \t too#much\nfun!";
        const 
    char toks[]="\t\n#";
    //    char *pt;
        
        
    puts(data);
        
    char *pt strtok(data,toks);
        while(
    pt){/* while(pt=(strtok(NULL,toks))); ?*/
            
    puts(pt);
            
    pt=strtok(NULL,toks);
        } 
    this fragment takes the return value of strtok and assigns it to char *pt when its declared as well. Thus initialising it as well. What is the difference between these two fragments and the code with fgets. Does fgets not return a char * as well.?

    Thanks in advance.
    Last edited by caroundw5h; 08-29-2004 at 09:30 AM.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  11. #11
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >intitilaizing find to its return value seems to work fine.
    Yes, because strchr returns a pointer to a character inside of line. The memory already exists and you own it, so find is simply assigned the reference.

    >What is the difference between these two fragments and the code with fgets.
    The same thing; the memory you are assigning the pointer to point to already exists and you own it. The code with fgets attempts to modify an uninitialized pointer, it really has nothing to do with the return value, but the argument you pass to the function.
    My best code is written with the delete key.

  12. #12
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Before you can work with the memory that a pointer points to, you must assign it to memory that you own, like so (without dynamic allocation):
    Code:

    char buffer[MAX];
    char *name = fgets ( buffer, MAX, stdin );
    Ok, I think i'm getting it. The other functions didn't point to some random memory locations they had specific places in memory dictated by their return values.
    Code:
    char *name = fgets(name,MAX,stdin)
    wasn't any memory i had. I'll let it saturate some more. Thanks guys
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  13. #13
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Just an example of the possible problems when you point to memory you should:
    Code:
    #include <stdio.h>
    
    void foo(void);
    void bar(void);
    
    int main (void)
    {
      foo();
      bar();
      return 0;
    }
    
    void foo (void)
    {
      char ch;
      char *ptr = &ch + 8;
      char *ptr2;
      puts("Please enter your name: ");
      ptr2 = fgets (ptr, 50, stdin);
      printf("Welcome %s\n", ptr2);
    }
    
    void bar (void)
    {
      puts("I'm in bar");
    }
    My output:
    Please enter your name:
    Thantos
    Welcome Thantos

    Segmentation fault
    Basically I setup ptr in such a way that it would over write the return address. Now I purposely did it to show what can happen but when you work with an uninitalized pointer it *could* have a value that points to a location that holds a return address.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. Compiling c++ intrinsics commands
    By h3ro in forum C++ Programming
    Replies: 37
    Last Post: 07-13-2008, 05:04 AM
  3. Help calling function is asm
    By brietje698 in forum C++ Programming
    Replies: 24
    Last Post: 12-06-2007, 04:48 PM
  4. Inline asm
    By brietje698 in forum C++ Programming
    Replies: 5
    Last Post: 11-11-2007, 02:54 PM
  5. Getting position from game..
    By brietje698 in forum C++ Programming
    Replies: 1
    Last Post: 10-26-2007, 12:15 PM