Thread: Argghghghghgh!!!!

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

    Argghghghghgh!!!!

    I have the following code
    Code:
    #include <stdio.h>
    #include <stdlib.h> // for getenv. don't implicit call this function
    #include "functions.h"
    
    void Form(void){
        /*if REQUEST_METHOD == GET */
       char *GETS = getenv("QUERY_STRING");
       /*gets query string up to \0 and assignes to GETVALUE */
       
       
       /*if REQUEST_METHOD == POST */
       char *formLength =  getenv("CONTENT_LENGTH");
       long size = atol(formLength);
       char hold[size];
       
      if ( (GETS) !=NULL){
          decodeUrl(GETS);
          fprintf(stdout,"<p>%s</p>",GETS);
      }    
    
      
      else{ //method was post. now parse accordingly. 
       printf("The submission size is %d characters.", size);
       
         if( ( fgets(hold,size,stdin) ) !=NULL)
           decodeUrl(hold);             
                         
       fprintf(stdout, "<p>%s</p>",hold);
            
    }   //end of else       
         
      
      
      return;
      
    }
    where decodeUrl is defined as
    Code:
    #include "functions.h"
    
    void decodeUrl(char *str){
        /*this function looks for all the characters '+' and '&' and replaces them with
        a space and a '\n' respectively. It also converts all hexadecimal values to their
        decimal equivalent. Converting ox to decimal should not be done on textarea and 
        other text type input in case end user meant for that to happen */
        while (*str++ ){
            puts(str);
            if ( *str == '+')
               *str = ' ';
               
            if ( *str == '&')
              *str = '\n';
          }
      }

    Now when I run this code it works fine. However attempting to duplicate it. I coded the follwoing:
    Code:
    #include <stdio.h>
    void decodeUrl (char *str);
    int main(void){
        
        char hold[]="this + *990))^%$#&^%$#21+++)(*&^%$4";
        char *hold2="this + *990))^%$#&^%$#21+++)(*&^%$4";
        
        decodeUrl(hold);
        decodeUrl(hold2);
        puts(hold);
        puts(hold2);
        
        getchar();
        return 0;
    }    
    
    void decodeUrl(char *str){
        /*this function looks for all the characters '+' and '&' and replaces them with
        a space and a '\n' respectively. It also converts all hexadecimal values to their
        decimal equivalent. Converting ox to decimal should not be done on textarea and 
        other text type input in case end user meant for that to happen */
        while (*str++ ){
           // puts(str);
            if ( *str == '+')
               *str = ' ';
               
            if ( *str == '&')
              *str = '\n';
          }
      }
    And lo and behold I'm crashing my program. What am I not seeing. Everytime I think I have a hold on this language I get another surprise ...seemngly...
    I'm going back over my chapters on arrays, pointers and char arrays, but in the meantime, someone enlighten me please...
    Warning: Opinions subject to change without notice

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

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
     char *hold2="this + *990))^%$#&^%$#21+++)(*&^%$4";
    hold2 is a string literal, and you're trying to modify it. Bad caroundw5h!

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Greetings,

    This is simple to fix. At least to stop the crashing. Let's look at our line that crashes:
    Code:
    char *hold2;
    This line is a pointer to nothing. All pointers do is "point to" an existing memory object. Your program crashes because you are trying to write to memory that isn't yours, and/or you are writing to memory that doesn't exist.

    The unary operator & gives the address of an object. Simple enough, we could write something similar to the lines of:
    Code:
    char abc[25];
    char *hold2 = &abc[0];
    Though this isn't always recommended. The best way to retrieve an empty block of memory, in C, is malloc().

    Pointers are nothing until you "initialize" them the right way. Usually you could create an array and use it immediately, though there are differences with pointers and their elements.


    - Stack Overflow
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  4. #4
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Thank you both for your responses. Quazah I assumed as much, but to be quite frank I assumed I was simply redirecting the ptr to point elsewhere on each occurance of the tokens I was looking for. Not to mention I cannot understand why the preceeding code worked.
    I'm going over those 3 extensive chapters again to find my stupidity and I will be back.
    Thank you guys again.
    Warning: Opinions subject to change without notice

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

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Stack Overflow
    Greetings,

    This is simple to fix. At least to stop the crashing. Let's look at our line that crashes:
    Code:
    char *hold2;
    This line is a pointer to nothing. All pointers do is "point to" an existing memory object. Your program crashes because you are trying to write to memory that isn't yours, and/or you are writing to memory that doesn't exist.
    No, you're wrong. It is pointing to something. It's pointing to a string literal:
    Code:
    int main(void){
        
        char hold[]="this + *990))^%$#&^%$#21+++)(*&^%$4";
        char *hold2="this + *990))^%$#&^%$#21+++)(*&^%$4";
        
        decodeUrl(hold);
        decodeUrl(hold2);
        puts(hold);
        puts(hold2);
        
        getchar();
        return 0;
    }
    On the second colored line, we pass a string literal to the function decodeUrl, which then attempts to modify it. That's why it crashes.

    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    Quote Originally Posted by caroundw5h
    Code:
       /*if REQUEST_METHOD == POST */
       char *formLength =  getenv("CONTENT_LENGTH");
       long size = atol(formLength);
       char hold[size];
    Wasn't this suposed not to compile????

  7. #7
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Quote Originally Posted by xErath
    Wasn't this suposed not to compile????
    how's that? The code is pretty straight forward.
    Warning: Opinions subject to change without notice

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

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I believe he's referring to the variable sized array. C99 allows for this.

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Hello,

    While overviewing array declaration I did notice that it works as the following:
    Code:
    array[constant-expression]
    This tells us that your element declaration must be constant. Also, we know that a variable declared as the following is not constant:
    Code:
    long size;
    Because size can change at any time. Most compilers should tell you that this is not permitted too.


    - Stack Overflow
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  10. #10
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    and what if i had done this
    Code:
    char *hold = malloc(size * sizeof( char ) )
    what difference does it make?
    Warning: Opinions subject to change without notice

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

  11. #11
    The function malloc() returns a block of memory of your requested size. It is not dependant upon constant variables. You can send a fixed number or even a variable to malloc(). Of course as long as it is size_t. You can type cast your variables too.

    - Stack Overflow
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  12. #12
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Quote Originally Posted by Stack Overflow
    The function malloc() returns a block of memory of your requested size. It is not dependant upon constant variables. You can send a fixed number or even a variable to malloc(). Of course as long as it is size_t. You can type cast your variables too.

    - Stack Overflow
    and there you have it. it evaluates to pretty much the same thing. another argument as to why c99 was a ridiculous additon. I used what was available but point taken.
    Warning: Opinions subject to change without notice

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

  13. #13
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Because size can change at any time. Most compilers should tell you that this is not permitted too.
    Actually it is quite permissible under the most recent standard (as quzah already pointed out).

Popular pages Recent additions subscribe to a feed