1

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 
Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
pottsork
  • 33
  • 6
  • 1
    Your program is rather long. Could you try to narrow it down? – fuz Dec 24 '15 at 12:01
  • 1
    Welcome to Stack Overflow! [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Dec 24 '15 at 12:02
  • 3
    Welcome to Stack Overflow! Please see [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/q/5431941/2173917) – Sourav Ghosh Dec 24 '15 at 12:02
  • 1
    Welcome to Stack Overflow! Please read [Ask] page first. – Sourav Ghosh Dec 24 '15 at 12:02
  • Possible duplicate of [Getting Segmentation Fault](http://stackoverflow.com/questions/5834032/getting-segmentation-fault) – Michael Kruglos Dec 24 '15 at 12:09
  • `while (!feof(fp)) {...}` is always wrong (and in this case, the string will not be null terminated) – joop Dec 24 '15 at 12:16

1 Answers1

1

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.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97