C - 存储到空指针错误,段错误

标签 c pointers encryption segmentation-fault cs50

请耐心等待我的代码。我是 C 语言的初学者。下面的代码构建了一个维吉尼亚密码。用户输入一个key参数,用于加密明文消息。该代码将输出密文

我收到的错误如下。请注意,我还没有研究过指针。

任何诊断错误的帮助将不胜感激!

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

代码

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

}

最佳答案

您收到此错误消息是因为变量 yNULL .

类型string实际上是一个typedef (换句话说,是别名)到 char *这意味着“指向 char 的指针”,因此 y是一个指向 char 的指针。

当你在做y[i]时,您取消引用 NULL这是不允许的并会导致错误的指针。 NULL代表一个不存在的内存空间,所以你不能在这里存储你的密文!

要解决此问题,您可以声明并初始化 y如下:

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

您必须#include <stdlib.h>为了使用calloc()函数。

现在,y是一个指向大小为 t 的内存空间的指针(明文和密文具有相同的大小),您可以取消引用并将数据写入!

在继续之前,您绝对应该了解指针和内存的工作原理。一些程序员老兄在您原始帖子的评论中发布了一份很棒的书籍 list ,请看一下!

关于C - 存储到空指针错误,段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45318219/

相关文章:

c - C语言中声明void**是什么意思?

c - 在汇编中实现矩阵 vector 乘法

c - 用C中的另一个字符串替换子字符串

C 程序 - 发送 SIGTERM 信号后进程不调用

c - case 和 default 是否被视为陈述?

c++ - 分配 std::shared_ptr

c++ - 在堆栈上取消引用变量或最近取消引用的成本?

email - 使用 Apache Camel 进行邮件签名和加密

java - 异常没有被它的 catch block 捕获,然后该方法抛出另一种异常

android - 使用 AES 解密 SQLite 数据库