Search code examples
caccess-violation

Access violation reading location 0x00000000 in C


Im getting

Access violation reading location 0x00000000

while i try to run my program. I can build the program with no errors at all, but when i try to run it, it crashes. I read here at StackOverflow that this problem occurs when there is pointers pointing at nothing. I have searched the code without any success. Anyone here who might know where the problem is?

main.c

#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
#define FILENAME 256


/*
* 
*/



int main(int argc, char** argv) {


char * data = readFromFile("input.txt");
int arrLength = getArrayLength(data);
char * encryptedData = (char *)malloc(arrLength * sizeof(char) + 1 * sizeof(char));
decrypt(data, arrLength, 1, encryptedData);
encrypt(data, arrLength, 1, encryptedData);
int menu = 0;
int key;

printf("Enter 1 for decrypt or 2 for encrypt from input.txt");

scanf("%d", &menu);
if (menu == 1) {
    printf("Enter key:");
    scanf("%d", &key);
    encrypt(data, arrLength, key, encryptedData);

}
else {
    printf("Enter key:");
    scanf("%d", &key);
    decrypt(data, arrLength, key, encryptedData);
}

writeToFile("output.txt", encryptedData);

printf("\n Enter any key to exit 11: ");
getchar();
return (1);
}

functions.c

#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
char * readFromFile(char * fileName) {
FILE *fp;
char c;
if ((fp = fopen(fileName, "r")) == NULL) {
    puts("Error: input file invalid");
    return NULL;
}

int count = 0;
while ((c = fgetc(fp) != EOF)) count++;
rewind(fp);
char *data = (char *)malloc(count * sizeof(char) + 1 * sizeof(char));
count = 0;
while (!feof(fp)) {
    fscanf(fp, "%c", &data[count++]);
}

fclose(fp);
return data;
    }

    void writeToFile(char * fileName, char *data) {
FILE *fp;
if ((fp = fopen(fileName, "w")) == NULL) {
    puts("Error: output file invalid");
}
else {
    int i = 0;
    while (data[i] != '\0') {
        fputc(data[i], fp);
        i++;
    }
    fclose(fp);
}
    } 

    int encrypt(char *plainText, int arrLength, int key, char *cipherText) {
if (key > 25 || key < 1) {
    puts("Error: invalid key");
    return 0;
}
for (int i = 0; i < arrLength; i++) {
    if ((plainText[i] >= 97 || plainText[i] <= 122) || (plainText[i] >= 65 || plainText[i] <= 90)) {
        // only encrypt alpha characters
        cipherText[i] = plainText[i] + key;
    }
    else {
        cipherText[i] = plainText[i];
    }
}
return 1;
    }
    int decrypt(char *plainText, int arrLength, int key, char *cipherText) {
if (key > 25 || key < 1) {
    puts("Error: invalid key");
    return 0;
}
for (int i = 0; i < arrLength; i++) {
    if ((plainText[i] >= 97 || plainText[i] <= 122) || (plainText[i] >= 65 || plainText[i] <= 90)) {
        // only decrypt alpha characters
        cipherText[i] = plainText[i] - key;
    }
    else {
        cipherText[i] = plainText[i];
    }
}
return 1;
    }
    int getArrayLength(char *data) {
int i = 0;
while (data[i] != '\0') {
    i++;
}
return i;
}

functions.h

#ifndef MY_FUNCTION
#define MY_FUNCTION

char * readFromFile(char * fileName);
void writeToFile(char * fileName, char *data); 
int encrypt(char *plainText, int arrLength, int key, char *cipherText);
int decrypt(char *plainText, int arrLength, int key, char *cipherText);
int getArrayLength(char *data);

#endif 

Solution

  • The actual error means a NULL pointer dereference probably because you never check the return value of malloc(), another thing you must check is the return value of scanf().

    Also, you never nul terminate the read data from the file, nor the data you encrypt()/decrypt(). And yet you treat it as a when you try code like

    while (data[i] != '\0')
        i++;
    

    I am assuming that you are not allowed to use strlen(), because that's exactly what strlen() does.

    Also, you don't need to iterate through every byte in the file to calculate it's length. Try this instead

    #include <stdio.h>
    #include <stdlib.h>
    
    #define FILENAME 256
    
    char *
    readFromFile(char * fileName)
    {
        FILE *fp;
        size_t length;
        char *data;
    
        if ((fp = fopen(fileName, "r")) == NULL)
        {
            puts("Error: input file invalid");
            return NULL;
        }
    
        fseek(fp, 0L, SEEK_END);
        length = ftell(fp);
        rewind(fp);
    
        data = malloc(length + 1);
        if (data == NULL)
        {
            puts("Error: allocating memory");
            fclose(fp);
            return NULL;
        }
    
        if (fread(data, 1, length, fp) < length)
        {
            puts("Error: reading from the file");
    
            free(data);
            fclose(fp);
            return NULL;
        }
        // `nul' terminate please
        data[length] = '\0';
        puts(data);
        fclose(fp);
    
        return data;
    }
    
    void
    writeToFile(char * fileName, char *data)
    {
        FILE *fp;
        if ((fp = fopen(fileName, "w")) == NULL)
            puts("Error: output file invalid");
        else
        {
            for (int i = 0 ; data[i] != '\0' ; ++i)
                fputc(data[i], fp);
            fclose(fp);
        }
    }
    
    int
    encrypt(char *plainText, size_t arrLength, int key, char *cipherText)
    {
        if (key < 25 && key >= 1)
        {
            for (size_t i = 0 ; i < arrLength ; i++)
            {
                if ((plainText[i] >= 97 || plainText[i] <= 122) || (plainText[i] >= 65 || plainText[i] <= 90))
                {
                    // only encrypt alpha characters
                    cipherText[i] = plainText[i] + key;
                }
                else
                {
                    cipherText[i] = plainText[i];
                }
            }
            // `nul' terminate please
            cipherText[arrLength] = '\0';
            return 1;
        }
        puts("Error: invalid key");
        return 0;
    }
    int
    decrypt(char *plainText, size_t arrLength, int key, char *cipherText)
    {
        if (key < 25 && key >= 1)
        {
            for (size_t i = 0; i < arrLength ; i++)
            {
                if ((plainText[i] >= 97 || plainText[i] <= 122) || (plainText[i] >= 65 || plainText[i] <= 90))
                {
                    // only decrypt alpha characters
                    cipherText[i] = plainText[i] - key;
                }
                else
                {
                    cipherText[i] = plainText[i];
                }
            }
            // `nul' terminate please
            cipherText[arrLength] = '\0';
            return 1;
        }
        puts("Error: invalid key");
        return 0;
    }
    
    int
    getArrayLength(char *data)
    {
        size_t length;
        for (length = 0 ; data[length] != '\0' ; ++length);
        return length;
    }
    
    int
    main(int argc, char** argv)
    {
        char * data;
        int arrLength;
        char *encryptedData;
        int menu = 0;
        int key;
    
        data = readFromFile("input.txt");
        if (data == NULL)
            return -1;
        arrLength = getArrayLength(data);
        encryptedData = malloc(arrLength + 1);
        if (encryptedData == NULL)
            return -1;
        decrypt(data, arrLength, 1, encryptedData);
        encrypt(data, arrLength, 1, encryptedData);
    
        printf("Enter 1 for decrypt or 2 for encrypt from input.txt ");
    
        if (scanf("%d", &menu) != 1)
            return -1;
        if (menu == 1)
        {
            printf("Enter key: ");
            if (scanf("%d", &key) != 1)
                return -1;
            encrypt(data, arrLength, key, encryptedData);
        }
        else
        {
            printf("Enter key: ");
            if (scanf("%d", &key) != 1!)
                return -1;
            decrypt(data, arrLength, key, encryptedData);
        }
        writeToFile("output.txt", encryptedData);
    
        printf("\n Enter any key to exit 11: ");
    
        free(data);
        free(encryptedData);
        return (1);
    }
    

    Note that I don't mix declarations with statements, because that makes the code harder to read and understand.