0

So as stated in the title, my problem is that a null pointer is being passed to something in my Vigenere encoder.

Here is my code. I will explain what I find to be the problem and give the error message I get as output.

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

bool StrIsAlpha();
string VigEncrypt();
int CharToAlphabIndex(char c);
char AlphabIndexToChar(int aIndex, bool caps);
bool isCaps(char c);

int main(int argc, string argv[])
{
    if((argc > 2 || argc == 1) || !(StrIsAlpha(argv[argc - 1]))){
        printf("Usage: ./vigenere keyword\n");
        return 1;
    }

    string pText = get_string("plaintext: ");
    printf("ciphertext: %s\n",VigEncrypt(pText));
}

string VigEncrypt(string keyword, string pText){
    string vigText = pText; // What we will encrypt

    int maxKeyChar = strlen(keyword); // So we don't go out of length of the keyword
    int currentKeyChar = 0; // Which letter of the key we currently are on

    for(int i = 0; i < strlen(pText); i++){
        bool charCaps = isCaps(vigText[i]);
        char vigChar = CharToAlphabIndex(vigText[i]); // Getting the current character we are on and then converting it to an alphabet index

        vigChar += CharToAlphabIndex(keyword[currentKeyChar]);
        vigChar %= 26; // Warping A to Z
        vigChar = AlphabIndexToChar(vigChar, charCaps); // ASCII value again
        vigText[i] = vigChar; // Editing the string to encrypt

        currentKeyChar++;
        if(!(currentKeyChar < maxKeyChar)){
            currentKeyChar = 0;
        }
    }

    return vigText;
}

int CharToAlphabIndex(char c){
    int alphabIndex;

    if(c >= 'A' && c <= 'Z'){
        alphabIndex = c - 'A'; // c - 65;
    }else{
        alphabIndex = c - 'a'; // c - 97;
    }

    return alphabIndex;
}

char AlphabIndexToChar(int aIndex, bool caps){
    char c = aIndex;

    if(caps){
        c += 'A';
    }else{
        c += 'a';
    }

    return c;
}

bool isCaps(char c){
    if(c >= 'A' && c <= 'Z'){
        return true;
    }
    return false;
}

bool StrIsAlpha(string inpString){
    for(int i = 0; i < strlen(inpString); i++){
        if(!((isalpha(inpString[i])))){
            return false;
        }
    }
    return true;
}

By the way, an alphabet index in my program is where a character is in the alphabet (e.g a = 1, b = 2, c = 3, z = 26, etc).

Ok, here is the error message.

$ ./vigenere abcab
plaintext: hello
vigenere.c:29:31: runtime error: null pointer passed as argument 1, which is declared to never be null
/usr/include/string.h:385:33: note: nonnull attribute specified here
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==664==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fd42e0695a1 bp 0x7fffbb2f3f80 sp 0x7fffbb2f3e18 T664)
==664==The signal is caused by a READ memory access.
==664==Hint: address points to the zero page.
    #0 0x7fd42e0695a0  /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/multiarch/strlen-avx2.S:59
    #1 0x4281d2 in VigEncrypt /root/sandbox/vigenere.c:29:24
    #2 0x42811a in main /root/sandbox/vigenere.c:20:31
    #3 0x7fd42defcb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #4 0x402b49 in _start (/root/sandbox/vigenere+0x402b49)

UndefinedBehaviorSanitizer can not provide additional info.
==664==ABORTING

So here's what I think is happening.

On line 29, I am passing pText, which is apparently a null value (or pointer??). I tried seeing if the loop ever executes at all and it only executes once and then the whole program errors. I don't know how in the world it is becoming null.

1 Answer 1

1

Welcome to the community. Your program is a real mess of functions for a relatively simple task, the purpose of the use of functions is to perform specific tasks outside of main (), in order to keep the code readable, that the logical flow is easy to follow. Five functions for Vigenere seem excessive to me. Well, everything is a matter of preferences. Let's see what is your error, it occurs because during the execution of the program a null value (pText = 0x0) is passed to the string function VigEncrypt (). You will ask yourself why, if the value of pText is not zero.

The whole problem is caused by the VigEncrypt () function. Look at the three uses that you give to this function:

// prototype
string VigEncrypt ();
// definition of the function
string VigEncrypt (string keyword, string pText)
// call the function in main
VigEncrypt (pText)

This is not good. I do not know the internal operation of the C compiler in the IDE, but in the C language we must declare the function with a return type and the types of the different arguments, separated by commas (surprisingly you do well with some functions, but not with other ), and we must be consistent with the types of variables, and their number, which we pass to the function. It seems that the IDE will accept the first argument for the VigEncrypt function, but the second argument becomes zero for the compiler. Remember: type of the arguments and number of arguments, to use correctly this function you must be consistent.

// prototype
string VigEncrypt (string keyword, string pText);
// definition of the function
string VigEncrypt (string keyword, string pText)
    {
     ....
    }
// call the function in main
VigEncrypt (keyword, pText);
1
  • Thank you so much! I thought that if I declared the function at the top and then where I wrote the function at the bottom, if I wrote different arguments in that function, the bottom function's arguments would override the top reference's arguments. This didn't, however, work for the functions which required the type char so I had a feeling this was wrong how I was doing it. I was also writing the code at night and was a bit tired so that is why there might have been a few silly mistakes I didn't see before. Commented Mar 4, 2019 at 3:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .