访问冲突读取位置0x00000000在C中

时间:2015-12-24 12:00:30

标签: c access-violation

我得到了

  

访问冲突读取位置0x00000000

当我尝试运行我的程序时。我可以在没有任何错误的情况下构建程序,但是当我尝试运行它时,它会崩溃。我在StackOverflow上看到,当指针指向任何东西时会出现此问题。我搜索了代码没有任何成功。这里有谁可能知道问题出在哪里?

的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 

1 个答案:

答案 0 :(得分:1)

实际错误意味着NULL指针取消引用可能是因为您从未检查malloc()的返回值,您必须检查的另一件事是scanf()的返回值。

此外,您永远不会nul终止文件中的读取数据,也不会终止您encrypt() / decrypt()的数据。然而,当您尝试像

这样的代码时,您会将其视为
while (data[i] != '\0')
    i++;

我假设您不能使用strlen(),因为这正是strlen()所做的。

此外,您不需要遍历文件中的每个字节来计算它的长度。试试这个

#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);
}

请注意,我不会将声明与语句混合,因为这会使代码更难以阅读和理解。