Exc_bad_access?

Discussion in 'Mac Programming' started by Halfmaster1, Mar 18, 2011.

  1. Halfmaster1 macrumors newbie

    Joined:
    Dec 28, 2010
    #1
    I am getting an error am getting that ^ error in this code:

    Code:
    i=0; ii=0;
    	while (i!=11)
    	{
       here-->  evolvingWords[i][ii]=randomChar(rand());
    		ii++;
    		if (ii=8); 
    		{
    			ii=0;i++;
    		}
    	}
    	i=0; ii=0;
    
    int randomChar(int convert)
    {
    	switch (convert%26) 
    	{
    		case 0:
    			return 'a';
    			break;
    		case 1:
    			return 'b';
    			break;
    		case 2:
    			return 'c';
    			break;
    		case 3:
    			return 'd';
    			break;
    		case 4:
    			return 'e';
    			break;
    		case 5:
    			return 'f';
    			break;
    		case 6:
    			return 'g';
    			break;
    		case 7:
    			return 'h';
    			break;
    		case 8:
    			return 'i';
    			break;
    		case 9:
    			return 'j';
    			break;
    		case 10:
    			return 'k';
    			break;
    		case 11:
    			return 'l';
    			break;
    		case 12:
    			return 'm';
    			break;
    		case 13:
    			return 'n';
    			break;
    		case 14:
    			return 'o';
    			break;
    		case 15:
    			return 'p';
    			break;
    		case 16:
    			return 'q';
    			break;
    		case 17:
    			return 'r';
    			break;
    		case 18:
    			return 's';
    			break;
    		case 19:
    			return 't';
    			break;
    		case 20:
    			return 'u';
    			break;
    		case 21:
    			return 'v';
    			break;
    		case 22:
    			return 'w';
    			break;
    		case 23:
    			return 'x';
    			break;
    		case 24:
    			return 'y';
    			break;
    		case 25:
    			return 'z';
    			break;
    			
    	}
    	return 0;
    }

    I know that rand() isn't a good function, but It doesn't need to be extremely random, so I wasn't to worried. Anyways, If anyone can help, it would be appreciated.

    Thanks.
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Please post all your code, so we can compile and run it.

    We don't know what evolvingWords is.

    With that said, i = 8 evaluates to 8. 8 is not 0, so if (8) is always true. = for assignment, == for comparison.

    Why did you build a crazy Rube Goldberg while structure when nested for loops would be much clearer?

    -Lee
     
  3. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #3
    What's with the crazy switch() statement ? Remove the entire randomChar() function and just add 97 to rand()%26 to get the same result (or use 65 for upper case letters).

    I'll agree with lee1210. Rewrite the code and use nested for() loops and fix your misuse of the assignment operator instead of the comparison operator.

    Could should work afterwards depending on how evolvingWords is initialized.
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    Or just add 'a' or 'A' to rand()%26 so you don't have to lookup the ASCII values.

    Code:
    char randomChar() { return (char)((rand()%26)+'a'); }
    
    Taking a value as an argument seems confusing. There's nothing random happening in your randomChar.

    -Lee
     
  5. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #5
    A good point and much more portable.
     
  6. Halfmaster1, Mar 19, 2011
    Last edited: Mar 19, 2011

    Halfmaster1 thread starter macrumors newbie

    Joined:
    Dec 28, 2010
    #6
    I never really understood what for loops were for. Instead of

    Code:
    for(i=0;i<20;i++)
    {
    //code
    }
    , why not just have

    Code:
    i=0;
    while(i<20)
    {
    i++;
    //code
    }

    Anywheys, if you can show me a better way, go ahead, I just use this to help me find a value closest to [0][0] in an array, and I thought it would work for this.


    Anywheys, it turns out that the error was just a typo. I hate it when that happens, searching for the problem for a while, and after posting a topic and everything. I have came across a new problem, though, in a similar area.

    Code:
    char evolvingWords[9][9];
    		
    		i=0;
    		while (!(i==10))
    		{
    			if (ii==11) 
    			{ii=0; i++;}
    			
    			
    			evolvingWords[i][ii]=0;
    			i++;
    		}
    		i=0;
    
    
    
    
    	i=0; ii=0;
    	while (i!=10)
    	{
    		evolvingWords[i][ii]=rand()%26+'a';
    		ii++;
    		if (ii==8); 
    		{
    			ii=0;i++;
    		}
    	}
    	i=0; ii=0;
    	
    	printf("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s.", evolvingWords[0],evolvingWords[1],evolvingWords[2],evolvingWords[3],evolvingWords[4],evolvingWords[5],evolvingWords[6],evolvingWords[7],evolvingWords[8],evolvingWords[9]);
    	
    

    Yet the console says w\367\277_\377, c\300_\377, a, h\377, b, v, s, v, r, c\300_

    What? And why are some strings only one character long?

    Thanks.
     
  7. KnightWRX, Mar 19, 2011
    Last edited: Mar 19, 2011

    KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #7
    Fine then, why not skip the if and convulted logic and used nested while loops ?

    There's still a buffer overflow in your program. You declare a 9 x 9 array and then have the indexes jump up to 9 and 10. They should only go from 0 to 8. This is probably the partial source of your problem.

    for() loops are simply a cleaner, easier to read construct for incremental type loops. There is no real deeper meaning. Look at this :


    Code:
    char evolvingWords[9][9];
    int i, ii;
    
    for(i = 0; i < 9; i++)
        for(ii = 0; ii < 9; ii++)
            evolvingWords[i][ii]=0;
    for(i = 0; i < 9; i++)
        for(ii = 0; ii < 9; ii++)
            evolvingWords[i][ii]=rand()%26+'a';
    
    Isn't that much more readable and cleaner than your solution ?

    Also, I wouldn't treat your char arrays as strings since they aren't null terminated and this might cause a bunch of wacky stuff to go on in the ANSI C library. At least declare them to be longer (char evolvingWords[9][10];) and make sure to set that last char to '\0'.

    This is actually the way I'd do it :

    Code:
    #define MAX_WORDS 9
    #define MAX_LETTERS 10 
    char evolvingWords[MAX_WORDS][MAX_LETTERS];
    int i, ii;
    
    for(i = 0; i < MAX_WORDS; i++)
    {
        for(ii = 0; ii < (MAX_LETTERS - 1); ii++)
            evolvingWords[i][ii]=rand()%26+'a';
        evolvingWords[i][ii] = '\0';
        printf("%s ", evolvingWords[i]);
        fflush(stdout);
    }
    printf("\n");
    
    This resulted in the following output :

    Code:
    lrfkqyuqf jkxyqvnrt ysfrzrmzl ygfveulqf pdbhlqdqr rcrwdnxeu oqqeklait gdphcspij thbsfyfvl
    
    No need to loop twice over the array if you're going to set all the values to randoms anyhow, the initialization to 0 means nothing then, just a waste of cycles. Also, why not make the printing part of the loop itself to save on manually typing each array component ? No to mention what happens if you grow the array ? My solution would still print out the result without having to modify anything in the code but the size of the array, yours would require a bunch of extra copy/paste.

    All points to keep in mind, unless this homework assignment specifically asked to set the arrays to 0 before hand.

    Another point I'd like to add. Read up on the srand() function. As it stands, your use of rand() isn't very random at all.
     
  8. balamw, Mar 19, 2011
    Last edited: Mar 19, 2011

    balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #8
    I was going to say almost exactly what KnightWRX said.

    (EDIT: The main reason for loops are preferred here is that the range is clearly visible on one line and can thus be seen easier if you are going out of bounds on your array. Another easy way to provide sanity checking for that is to use an intermediate const variable or #define for the matrix dimensions. So the only change I would suggest to KnightWRX's code posted in the edit would be:

    Code:
    const unsigned char wordlength = 9;
    const unsigned char numwords = 9;
    
    char evolvingWords[numwords][(wordlength+1)];
    int i, ii;
    
    for(i = 0; i < numwords; i++)
    {
        for(ii = 0; ii < wordlength; ii++)
            evolvingWords[i][ii]=rand()%26+'a';
        evolvingWords[i][ii] = '\0';
        printf("%s ", evolvingWords[i]);
        fflush(stdout);
    }
    printf("\n"); 
    
    ).

    Plus, if you want to deal with them as chars deal with them as chars. Use "%c" in your printf instead of "%s".

    B
     
  9. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #9
    Give me time, my responses are often evolving as I edit them. I put in the #defines (don't like to waste memory space on constants that require a re-compile to change anyhow) on the 2nd to last edit. :D

    Though I do like the way you've incremented MAX_LETTERS on the initialization of the array rather than doing a substraction on the loop's condition. That is indeed better.
     
  10. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #10
    Mine too, but I'll usually check if there was any other activity on the thread before editing again to preserve continuity.

    Six of one half a dozen of the other. It's still memory even if it's defined as a literal in the code.

    I usually prefer to use consts during the debug phase as I like how they work in the typical debugger better. Plus a good optimizer compiler can basically take care of that and make the two approaches give the exact same machine code. (see e.g. http://stackoverflow.com/questions/...etween-define-const-and-enum-in-c-and-c-on-as )

    If I need to manually optimize later, I will.

    B
     
  11. Halfmaster1, Mar 19, 2011
    Last edited: Mar 19, 2011

    Halfmaster1 thread starter macrumors newbie

    Joined:
    Dec 28, 2010
    #11
    Thanks, it works now.


    Edit:
    Is there any easy way to see if to strings are the same?

    Thanks.
     
  12. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #12
    If you null-terminate them:
    if(strcmp(strA,strB) == 0) {
    ...
    }

    -Lee
     
  13. mif macrumors regular

    Joined:
    Feb 16, 2010
    Location:
    home

Share This Page