I'm implementing in c the vigenère algorithme.
Unfortunately when testing the program I'm experiencing a segmentation error. I'm compiling with clang on mac.
How could I avoid that error ?
Source Code:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
/**
* Function: invalidUsage
* --------------------
* Shows usage information and returns 1
*/
int
invalidUsage();
/**
* Function: cryptCaesar
* --------------------
* Returns encrypted char using caesar cipher
*/
char
cryptCaesar(const char plain, const int key);
/**
* Function: parseAlphaKey
* --------------------
* Converts an alpha string to a usable key (array of char from 0 to 25)
* Returns true if conversion successful, false if not
*/
bool
parseAlphaKey(const char* input_string, char** output_key);
// === Main ===
int main(int argc, const char *argv[])
{
// === Argument validation ===
char *output_key;
if (argc != 2
|| !parseAlphaKey(argv[1], &output_key))
return invalidUsage();
// === Read plain text ===
// === Output cipher text ===
//printf("%s\n", key);
return 0;
}
int
invalidUsage()
{
printf("Usage : vigenere <key>\n\n");
printf("KEY:\n");
printf(" Must be a string of alpha characters\n");
return 1;
}
char
cryptCaesar(const char plain, const int key)
{
char cipher;
if (islower(plain)) {
cipher = (plain - 'a' + key) % 26 + 'a';
} else if (isupper(plain)) {
cipher = (plain - 'A' + key) % 26 + 'A';
} else {
cipher = plain;
}
return cipher;
}
bool
parseAlphaKey(const char* input_string, char** output_key)
{
//output_key = NULL;
*output_key = malloc(strlen(input_string) * sizeof(char));
for (int i = 0, n = strlen(input_string); i < n; ++i) {
if (isupper(input_string[i]))
*output_key[i] = input_string[i] - 'A';
else if (islower(input_string[i]))
*output_key[i] = input_string[i] - 'a';
else {
//free(*output_key);
return false;
}
}
return true;
}
Debug output:
$ lldb vigenere -- test
Current executable set to 'vigenere' (x86_64).
(lldb) run
Process 48854 launched: '/Users/.../vigenere' (x86_64)
Process 48854 stopped
* thread #1: tid = 0x549580, 0x0000000100000d9f vigenere`parseAlphaKey(input_string=0x00007fff5fbff941, output_key=0x00007fff5fbff6a8) + 207 at vigenere.c:87, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0x2)
frame #0: 0x0000000100000d9f vigenere`parseAlphaKey(input_string=0x00007fff5fbff941, output_key=0x00007fff5fbff6a8) + 207 at vigenere.c:87
84 if (isupper(input_string[i]))
85 *output_key[i] = input_string[i] - 'A';
86 else if (islower(input_string[i]))
-> 87 *output_key[i] = input_string[i] - 'a';
88 else {
89 //free(*output_key);
90 return false;
(lldb) kill
Process 48854 exited with status = -1 (0xffffffff) SIGKILL
(lldb) exit
Regards
Two problems:
1) you're not terminating your output string - change:
*output_key = malloc(strlen(input_string) * sizeof(char));
to:
*output_key = malloc(strlen(input_string) + 1);
and make sure you add a '\0'
terminator, e.g. in parseAlphaKey
add a line:
(*output_key)[n] = '\0';
after the loop.
2) you're getting bitten by operator precedence - change, e.g.
*output_key[i] = input_string[i] - 'A';
to:
(*output_key)[i] = input_string[i] - 'A';