2

Please bear with my code. I'm a beginner in C. The code below builds a Vigenere cipher. The user inputs a key argument which is used to encrypt a plaintext message. The code will output the ciphertext.

The error I receive is as follows. Note that I have not studied pointers yet.

Any help in diagnosing the error would be greatly appreciated!

vigenere.c:47:13: runtime error: store to null pointer of type 'char'
Segmentation fault

The code

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(int argc, string argv[]){

// check for 2 arguments
if (argc != 2){

    printf("missing command-line argument\n");
    return 1;

} 

// check for character argument
int i,n;

for (i = 0, n = strlen(argv[1]); i < n; i++){

    if (!isalpha(argv[1][i])){

        printf("non-character argument\n");
        return 1;

    }

}

// if previous 2 checks are cleared, request 'plaintext' from user

printf("plaintext:");

// declare plaintext, key, and ciphertext

string t = get_string();    // plaintext
string u = argv[1];         // key (argument)
string y = NULL;            // ciphertext

// encode plaintext with key -> ciphertext

for (i = 0, n = strlen(t); i < n; i++){

    if (tolower(t[i])){

        y[i] = (char)((((int)t[i] + (int)tolower(u[i%n])) - 97) % 26) + 97;

    } else {

        y[i] = (char)((((int)t[i] + (int)tolower(u[i%n])) - 65) % 26) + 65;

    }


}


printf("ciphertext: %s\n", y);

}
akshayk07
  • 2,092
  • 1
  • 20
  • 32
kquach
  • 161
  • 1
  • 10
  • 1
    You attempt to dereference a null pointer and write to it? That should be pretty clear. And if you don't know about pointers then why are you *using* them? [Get a couple of good beginners books](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) and read. Learn first, use later. – Some programmer dude Jul 26 '17 at 05:36
  • 1
    `string y = NULL;` --> `string y = calloc(strlen(t)+1, sizeof(char)); ` – BLUEPIXY Jul 26 '17 at 05:38
  • `n = strlen(t); i < n;` : Use a different variable name for `n` here. – BLUEPIXY Jul 26 '17 at 05:41
  • 1
    On an unrelated note, please avoid using [*magic numbers*](https://en.wikipedia.org/wiki/Magic_number_(programming)). If by `97` you mean the [ASCII](http://en.cppreference.com/w/c/language/ascii) character `'a'` then *say* so. Or better yet, since you want to convert between upper and lover case use [`toupper`](http://en.cppreference.com/w/c/string/byte/toupper) and [`tolower`](http://en.cppreference.com/w/c/string/byte/tolower). You already use `toupper` but wrongly, you should be using [`isupper`](http://en.cppreference.com/w/c/string/byte/isupper) instead. – Some programmer dude Jul 26 '17 at 05:42
  • 4
    Regarding pointers, the type-name `string` is an alias for `char *`. It is a pointer type. This is one of the bad things about CS50 and its library, it makes you believe that you're not using pointers when in fact you are. While the CS50 library do hide some of the complexities of C, it does so to the detriment of learning C properly IMO. – Some programmer dude Jul 26 '17 at 05:45
  • 1
    `if (tolower(t[i])){` --> `if (islower((unsigned char)t[i])){` – BLUEPIXY Jul 26 '17 at 05:48
  • Get into the habit of using `valgrind` against your code. Use a `lint` checker outside of the compiler as well. – t0mm13b Jul 26 '17 at 05:50
  • @Someprogrammerdude Yep, and if you really need a magic number, but you don't know why you need it or why it has it's value, name it `strange_magic_number` or something. – klutt Jul 26 '17 at 05:52
  • @Someprogrammerdude *And if you don't know about pointers then why are you using them* That is because he doesn't know he is using pointers! The cs50 and it's "string" type strikes again! – Ajay Brahmakshatriya Jul 26 '17 at 06:44
  • @AjayBrahmakshatriya Yeah I noticed the CS50 part later. In my oppinion, learning from CS50 is almost worse than learning from "online judges". – Some programmer dude Jul 26 '17 at 06:48
  • 1
    @Someprogrammerdude wait? People __learn__ from online judges? – Ajay Brahmakshatriya Jul 26 '17 at 06:59
  • Thanks for all your input. I'll consult the books. – kquach Jul 26 '17 at 16:25

1 Answers1

3

You get this error message because variable yis NULL.

Type string is actually a typedef (an alias in other words) to char * which means "pointer to char" therefore y is a pointer to char.

When you are doing y[i], you dereference a NULL pointer which is not allowed and leads to an error. NULLrepresents a non-existing memory space so you can not store your ciphertext here !

To solve this problem you can declare and initialize y as follows :

char *y = calloc(strlen(t) + 1, sizeof(char)); // Ciphertext, ready to hold some data !

You will have to #include <stdlib.h>in order to use the calloc() function.

Now, y is a pointer to a memory space as large as t (plaintext and cyphertext have the same size) that you can dereference and write data to !

You should definitely learn about pointers and how memory works before going any further. Some programmer dude posted a great list of books in the comments of your original post, take a look at it !

Geo
  • 155
  • 9