Thread: how come I can exceed array scope

  1. #1
    Registered User
    Join Date
    Dec 2011
    Posts
    22

    how come I can exceed array scope

    In my struggle to learn C, I came across a situation where I can assign values to indices outside of array scope, or it seems to me I can. The code looks like this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
      unsigned char c;  
      char aoeui[1];
      srand (time(NULL));
      int i = 0;  
      while (i < 10)
        {     
          c = (rand() % 255); 
          if (isalnum(c))
        {      
          printf("%c\n", c); 
          aoeui[i] = c;
          ++i;      
        }
        }
      printf("----\n");
      printf("%s\n", aoeui);  
      return 0;
    }
    I tried to write the simplest possible random string generator. I declare an array of size 1:
    Code:
    char aoeui[1];
    But when it's printed,
    Code:
    printf("%s\n", aoeui);
    10 characters are printed on the screen, for example:
    Code:
    j
    O
    b
    j
    L
    5
    a
    q
    J
    N
    ----
    jObjL5aqJN
    I don't understand why it happens.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    C lets you get away with a lot of stupid things.
    Your program has actually two problems.
    Your'e overwriting array bounds and you try to print a string that is not zero terminated -> undefined behaviour. That means everything can happen. It can even apper to work correctly.
    Kurt

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    from Bounds checking - Wikipedia, the free encyclopedia

    "Many programming languages, such as C, never perform automatic bounds checking, to raise speed. However, this leaves uncaught many off-by-one errors and buffer overflows. Many programmers believe these languages sacrifice too much for rapid execution. "

  4. #4
    Registered User
    Join Date
    Dec 2011
    Posts
    22
    I didn't know about that. thanks.
    Is this program for generating random strings correct or would you change something:

    Code:
    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    int main(void)
    {
      char string[30];  
      /* Length of the password */
      unsigned short int length = 30;
     
      /* Seed number for rand() */
      srand((unsigned int) time(0) + getpid());
     
      /* ASCII characters 33 to 126 */
      while (length--) {
        string[length] = rand() % 94 + 33;    
      }
     
      printf("%s\n", string);  
      return EXIT_SUCCESS;
    }

  5. #5
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    @OP: take "incorrect"'s suggestion, but I'd recommend using character constants ('a') instead of numbers (94).

    > Many programmers believe these languages sacrifice too much for rapid execution.
    Not really relevant, but this belief is fallacious on so many levels. Part of the beauty of C is that it's directly translated into assembly, allowing the same speed with much greater portability. Adding any automatic checks like this that aren't present in assembly (unlike push/pop) defeats the purpose of this, especially when it's only designed to prevent human error.

    If anything, compilers could be written to produce warnings about out-of-bounds access, but still compile normally (you might sometimes want this for testing/etc.).

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by dmh2000 View Post
    "Many programming languages, such as C, never perform automatic bounds checking, to raise speed. However, this leaves uncaught many off-by-one errors and buffer overflows. Many programmers believe these languages sacrifice too much for rapid execution. "
    That is actually a religious view: something often put forward by zealots of other languages to justify a claim that their language of choice is better than C.

    As a matter of fact, no language performs bounds checking. It is compilers, interpreters, and other tools that perform bounds checking.

    In C, performance is one of the LEAST important reasons that compilers often don't do bounds checking. The most common reason is related to the equivalence (implicit conversion) between an array and a pointer. In that conversion, the bounds (or array size) information gets lost, so the compiler technically CAN'T do the checking unless it cross-checks all program code (not just one function) . It is possible (at a price) to obtain various tools (eg static analysers) that can perform bounds checking of C code.

    There are quite a few C compilers that do bounds checking on arrays. Albeit they can be fooled by code which makes heavy use of aliased pointers.

    While bounds checking by a compiler is useful, there are plenty of ways for bad code to (accidentally or deliberately) get past a compiler doing bounds checking. In my experience, folks with languages and compilers that explicitly do bounds checking are often over-confident about the quality of their code .....

    I'm not suggesting that C is better (or worse) than any other language. But I will take a disciplined C programmer, who writes code in a manner that avoids running off the end of arrays, over a sloppy <name your language> programmer who gets overconfident if their compiler does not diagnose issues on their code (such as out-of-bounds issues with arrays).
    Last edited by grumpy; 05-10-2012 at 04:35 AM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Dec 2011
    Posts
    22
    I've ended up with the following function:
    Code:
    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    void random_string(char * string, unsigned length)
    {
      /* Seed number for rand() */
      srand((unsigned int) time(0) + getpid());
      
      /* ASCII characters 33 to 126 */
      while (length--) {
        string[length] = rand() % 94 + 33;   
      }
    }
    
    int main(void)
    {
      char s[30];
      random_string(s, 30);  
      printf("%s\n", s);  
      return 0;
    }

  8. #8
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    You're forgetting the NULL terminator at the end of the string. Without that your printf will keep running through memory till you're not in Kansas anymore.
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  9. #9
    Registered User
    Join Date
    May 2012
    Posts
    1
    IMO it should be something like this:

    Code:
    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    void random_string(char * string, unsigned length)
    {
      /* Seed number for rand() */
      srand((unsigned int) time(0) + getpid());
      
      /* ASCII characters 33 to 126 */
      int i;  
      for (i = 0; i < length; ++i)
        {
          string[i] = rand() % 94 + 33;
        }
    
      string[i] = '\0';  
    }
    
    int main(void)
    {
      char s[31];
      random_string(s, 30);
      printf("%s\n", s);  
      return 0;
    }
    We need to make suere that string is terminated with '\0

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to access array outside its scope
    By shikhardeep in forum C++ Programming
    Replies: 1
    Last Post: 04-15-2012, 06:06 AM
  2. Why does this UL int appear to exceed its limit?
    By Kayl669 in forum C Programming
    Replies: 6
    Last Post: 08-29-2010, 01:06 AM
  3. Array of pointers not changing out of scope?
    By LaffyTaffy in forum C++ Programming
    Replies: 1
    Last Post: 07-29-2010, 12:17 PM
  4. Replies: 12
    Last Post: 05-13-2009, 06:41 AM
  5. Lot more just exceed
    By planet_abhi in forum C Programming
    Replies: 0
    Last Post: 11-18-2002, 02:24 AM