C 简单偏移加密中的分段错误

C 简单偏移加密中的分段错误,c,string,segmentation-fault,C,String,Segmentation Fault,好了,伙计们,这是我在这里的第一篇帖子。在我的compsci类中最近的一个赋值是,我们编写了两个函数,根据一个简单的偏移量对字符串进行编码和解码。到目前为止,在我的加密函数中,我试图将字符串中的大写字母转换为其ASCII等效值(一个int),添加偏移量(如果ASCII值超过'Z',则进行调整),将该int转换回字符(新的加密字符),并将其转换为新的字符串。我这里的编译很好,但当我运行它并输入简单的大写字符串时,它会给出一个分段错误(核心转储)。我哪里出了问题?(注意:有一些注释掉的位来自于试图解

好了,伙计们,这是我在这里的第一篇帖子。在我的compsci类中最近的一个赋值是,我们编写了两个函数,根据一个简单的偏移量对字符串进行编码和解码。到目前为止,在我的加密函数中,我试图将字符串中的大写字母转换为其ASCII等效值(一个int),添加偏移量(如果ASCII值超过'Z',则进行调整),将该int转换回字符(新的加密字符),并将其转换为新的字符串。我这里的编译很好,但当我运行它并输入简单的大写字符串时,它会给出一个分段错误(核心转储)。我哪里出了问题?(注意:有一些注释掉的位来自于试图解决在main中产生一些奇怪错误的情况)

#包括
#包括
#包括
//#包括
字符*加密(字符*str,整数偏移){
整数计数器;
char-medianstr[strlen(str)];
char*returnstr;//=malloc(sizeof(char)*strlen(str));
用于(计数器=0;计数器如果(charASCII+offset使用一组指针,但从不为它们分配任何内存,这将导致段错误

事实上,奇怪的是,似乎您知道您需要这样做,因为您已经准备好了代码,但您将其注释掉了:

char *returnstr;// = malloc(sizeof(char) * strlen(str));
使用指针时,需要将其“指向”分配的内存,指针可以指向通过
malloc()
请求的动态内存,也可以指向静态内存(例如声明的数组);使用动态内存后,需要
free()
它,但当你注释掉一个免费电话时,你似乎又知道这一点


只需一个
malloc()
inputstr
和一个用于
returnstr
的指针就足够了。

您使用一堆指针,但从不为它们分配任何内存。这将导致段错误

事实上,奇怪的是,似乎您知道您需要这样做,因为您已经准备好了代码,但您将其注释掉了:

char *returnstr;// = malloc(sizeof(char) * strlen(str));
使用指针时,需要将其“指向”分配的内存,指针可以指向通过
malloc()
请求的动态内存,也可以指向静态内存(例如声明的数组);使用动态内存后,需要
free()
它,但当你注释掉一个免费电话时,你似乎又知道这一点


只需将
malloc()
连接到
inputstr
和一个用于
returnstr
就足以实现此功能。

无需进一步说明,分段错误来自于使用scanf()

scanf()发生分段错误,因为它试图写入*inputstr(inputstr指向的位置块);此时未分配分段错误。 要调用scanf(),您需要输入一个指针,该指针指向的内存地址首先被分配

当然,要很好地修复分段错误,请将内存分配给char*inputstr

要动态分配128字节的内存(即指针将指向堆):

或者静态分配128字节的内存(即指针将指向堆栈):


不必进一步说明,分段错误来自于您对scanf()的使用

scanf()发生分段错误,因为它试图写入*inputstr(inputstr指向的位置块);此时未分配分段错误。 要调用scanf(),您需要输入一个指针,该指针指向的内存地址首先被分配

当然,要很好地修复分段错误,请将内存分配给char*inputstr

要动态分配128字节的内存(即指针将指向堆):

或者静态分配128字节的内存(即指针将指向堆栈):


encrypt()
函数的复杂性很大,这并不是必需的。请注意,在循环的每次迭代中计算字符串的长度通常是一个代价高昂的过程。我在一篇评论中指出:

90和64是怎么回事?为什么不使用“A”和“Z”?你已经注释掉了returnstr的内存分配,所以你是通过一个未初始化的指针进行复制然后返回的?这不是幸福的秘诀

其他答案也(准确地)指出,您尚未在
main()
中初始化指针,因此您没有机会在
encrypt()
中转储内核,因为您已经在
main()
中转储了内核

#包括
#包括
#包括
字符*加密(字符*str,整数偏移)
{
int len=strlen(str)+1;
char*returnstr=malloc(len);
if(returnstr==0)
返回0;
对于(int i=0;i‘Z’)
c='A'+(c-'Z')-1;
}
returnstr[i]=c;
}
返回返回str;
}

长变量名并不总是有用的;它们使代码更难阅读。请注意,
isupper()
为true的任何字符也满足
isalpha()
。对
isupper()的参数强制转换
防止在
char
类型有符号且无符号char值在0x80..0xFF范围内(高位已设置)时出现问题。使用强制转换,代码将正常工作;没有强制转换,您可能会遇到麻烦。

encrypt()中有很多复杂性
函数。请注意,在循环的每次迭代中计算字符串的长度通常是一个代价高昂的过程。我在一篇评论中指出:

90和64是怎么回事?为什么不用“A”和“Z”呢?你已经注释掉了
char *inputstr = (char *) malloc(128);
char inputstr[128];
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

char *encrypt(char *str, int offset)
{
    int len = strlen(str) + 1;
    char *returnstr = malloc(len);
    if (returnstr == 0)
        return 0;
    for (int i = 0; i < len; i++)
    {
        char c = str[i];
        if (isupper((unsigned char)c))
        {
            c += offset;
            if (c > 'Z')
                c = 'A' + (c - 'Z') - 1;
        }
        returnstr[i] = c;
    }
    return returnstr;
}