1

I have a problem with my program. Im making a simple codifying-prog with a dummy alfabeth, but when trying to access the char array it can't access the location, how come? I dont know if it has to do with the size_t type instead of int type?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>

static char * createAlfa(void);
char * codify(char *mess, char *alfa);

int
main(void)
{
    char *alfa=createAlfa();
    printf("write your mess to codify: \n");
    char mess[]="";
    scanf("%s", mess);
    char *code=codify(mess, alfa);
    printf("your codified message is: %s\n", code);
    return 0;
}

static char *
createAlfa(void)
{
    char *codealfa=malloc(sizeof(char)*27);
    srand((unsigned int)time(NULL));
    int i, ran;
    for(i=0; i<26; i++)
    {
        codealfa[i]='A'+i;
        if((ran=rand()%26)<i)
        {
            codealfa[i]=codealfa[ran];
            codealfa[ran]='A'+i;
        }
    }
    codealfa[26]=0;
    return codealfa;
}

char *
codify(char *mess, char *alfa)
{
    size_t len=strlen(mess);
    char *code=malloc(sizeof(char)*len);
    int i;
    for(i=0; i<len; i++)
    {
        int pos=(int)(toupper(mess[i])-'A');  //pos is behaving correctly, first loop is 
                                              //it is 15 when i write "potato"
        code[i]=alfa[pos];      //EXC_BAD_ACCESS, Could not access memory
    }
    code[i]=0;
    return code;
}
patriques
  • 5,057
  • 8
  • 38
  • 48
  • did you write out i and pos as the error occured? – Mario The Spoon Nov 21 '12 at 05:06
  • Hint: What is the value of `i` when the loop exits? Is that within the bounds of the array you made with `malloc`? – Billy ONeal Nov 21 '12 at 05:11
  • You have an off-by-one error at: `size_t len=strlen(mess); char *code=malloc(sizeof(char)*len);` in `codify()`. You need to add 1 to allocate enough space for the null too. Warning: I entered `potato` and got the 'codified' output POTATO one time; that's not a very good encryption. – Jonathan Leffler Nov 21 '12 at 05:12

3 Answers3

3

You are declaring mess as:

char mess[]="";

which makes its size equal to 1, to hold the NUL character. Next you are scanning your input in that array:

scanf("%s", mess);

which will not work, as there is not enough space.

To fix this you need to declare mess with correct size: one more than the length of the maximum number of characters you intend to store in it.

codaddict
  • 445,704
  • 82
  • 492
  • 529
3

I do believe that the problem is

char mess[]="";

There is no memory allocated for the string to be scanned into.

Replace it with

char mess[MAX_LENGTH];
mess[0] = 0;

Also be aware that scanf as you use it does not limit the length of the input, see How to prevent scanf causing a buffer overflow in C?

Community
  • 1
  • 1
Mario The Spoon
  • 4,799
  • 1
  • 24
  • 36
3

When I run the code under valgrind on Mac OS X, I get the output:

$ valgrind excbadacc
==80786== Memcheck, a memory error detector
==80786== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==80786== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==80786== Command: excbadacc
==80786== 
write your mess to codify: 
absintheabelones
==80786== Invalid write of size 1
==80786==    at 0x100000D1B: codify (excbadacc.c:53)
==80786==  Address 0x100007210 is 0 bytes after a block of size 16 alloc'd
==80786==    at 0xB823: malloc (vg_replace_malloc.c:266)
==80786==    by 0x100000CC5: codify (excbadacc.c:45)
==80786== 
==80786== Invalid read of size 1
==80786==    at 0xC894: strlen (mc_replace_strmem.c:398)
==80786==    by 0x1748C2: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==80786==    by 0x17318D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==80786==    by 0x17C2CF: printf (in /usr/lib/system/libsystem_c.dylib)
==80786==    by 0x100000DFA: main (excbadacc.c:18)
==80786==  Address 0x100007210 is 0 bytes after a block of size 16 alloc'd
==80786==    at 0xB823: malloc (vg_replace_malloc.c:266)
==80786==    by 0x100000CC5: codify (excbadacc.c:45)
==80786== 
your codified message is: AQBRSKHDAQDPZSDB
==80786== 
==80786== HEAP SUMMARY:
==80786==     in use at exit: 10,330 bytes in 36 blocks
==80786==   total heap usage: 36 allocs, 0 frees, 10,330 bytes allocated
==80786== 
==80786== LEAK SUMMARY:
==80786==    definitely lost: 43 bytes in 2 blocks
==80786==    indirectly lost: 0 bytes in 0 blocks
==80786==      possibly lost: 0 bytes in 0 blocks
==80786==    still reachable: 10,287 bytes in 34 blocks
==80786==         suppressed: 0 bytes in 0 blocks
==80786== Rerun with --leak-check=full to see details of leaked memory
==80786== 
==80786== For counts of detected and suppressed errors, rerun with: -v
==80786== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1)
$

One trouble is that you have an off-by-one error in codify() at:

size_t len=strlen(mess);
char *code=malloc(sizeof(char)*len);

You need to add 1 to allocate enough space for the null too.

Warning: for one run, I entered 'potato' and got the 'codified' output POTATO; that's not a very good encryption.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • And I see there's also the problem with the size of `mess`. There are limits to what even `valgrind` can do to help you. – Jonathan Leffler Nov 21 '12 at 05:17
  • @JonathanLeffler I have solved the problem already, but wanted to thank you for the input anyway, could only vote up.. I have not learned valgrind yet, but the more I program in C the more important it seems to be to know the tool.. – patriques Nov 21 '12 at 05:36