C 不规则分段断层

C 不规则分段断层,c,linux,ubuntu,segmentation-fault,cs50,C,Linux,Ubuntu,Segmentation Fault,Cs50,我正在尝试运行以下代码: #include <stdio.h> #include <string.h> int main(int argc, char const *argv[]) { /* code */ char senha [256]; if (argv[1] != NULL) { strcpy(senha, argv[1]); } ch

我正在尝试运行以下代码:

#include <stdio.h>
#include <string.h>

int main(int argc, char const *argv[]) {
        /* code */
        char senha [256];
        if (argv[1] != NULL)
        {
                strcpy(senha, argv[1]);
        }
        char frase [256];
        printf("Insira a frase: \n");
        scanf("%s", frase);
        int sizeS = (int)strlen(senha);
        int sizeF = (int)strlen(frase);
        char fraseout [sizeF+1];
        int i;
        int j;
        for (i=0; i<=sizeF-1; i++)
        {
                if(j>=sizeS)
                {
                        j=0;
                }
                int valF = (int)frase[i];
                int valS = (int)senha[j];
                valF = 32 + ((valF - 32) + (valS - 32)) % (128-32);
                fraseout[i] = (char)valF;
                j++;
        }
        fraseout[sizeF] = '\0';
        printf("\"%s\" -> \"%s\"\n", frase, fraseout);
        return 0;
}
#包括
#包括
int main(int argc,char const*argv[]{
/*代码*/
charsenha[256];
如果(argv[1]!=NULL)
{
strcpy(senha,argv[1]);
}
char frase[256];
printf(“Insira frase:\n”);
scanf(“%s”,frase);
int size=(int)strlen(senha);
int sizeF=(int)strlen(frase);
char fraseout[sizeF+1];
int i;
int j;
对于(i=0;i=尺寸)
{
j=0;
}
int valF=(int)frase[i];
int valS=(int)senha[j];
valF=32+((valF-32)+(valS-32))%(128-32);
fraseout[i]=(char)valF;
j++;
}
fraseout[sizeF]='\0';
printf(“\%s\”->\%s\“\n”,frase,fraseout);
返回0;
}

当我尝试在我的Ubuntu15.04上运行它时,它编译并运行得非常完美。当我尝试在OSX Yosemite上运行它时,它的编译和运行也完美无缺。但是,如果我在CS50虚拟机上编译并运行它,尽管编译运行良好,但运行时会出现分段错误。为什么会发生这种情况,为什么只在一个单一的操作系统上?

当j的初始值为0时,代码会工作。然而,这并不是假设所有(或任何)系统都存在这种情况,因此存在不同的行为。初始化j.

可能的问题,删除不相关的行。未初始化的可能是您的问题

argv[1]!=NULL在C89中是安全的,但不明确,可能不在不兼容的编译器中。检查
argc
更为典型

如果未传递参数,
senha
将保持未初始化状态,这可能会导致以后的缓冲区溢出

        char senha [256];
        if (argv[1] != NULL)
                strcpy(senha, argv[1]);
        char frase [256];
        scanf("%s", frase);
不检查输入缓冲区的大小,使用
scanf(“%255s”,frase)

如果不检查
scanf
的返回值,如果失败,
frase
将保持未初始化状态,这可能会导致以后的缓冲区溢出

        char senha [256];
        if (argv[1] != NULL)
                strcpy(senha, argv[1]);
        char frase [256];
        scanf("%s", frase);
VLA不在C89中,但在C99中,并作为GNU C89中的扩展提供,GNU C89是gcc使用的默认值。这可能无法使用严格的C89编译器编译

        int sizeF = (int)strlen(frase);
        char fraseout [sizeF+1];
未初始化

    int j;
此计算可能会产生一个
,导致不正确引用的输出

                valF = 32 + ((valF - 32) + (valS - 32)) % (128-32);
                fraseout[i] = (char)valF;
        printf("\"%s\" -> \"%s\"\n", frase, fraseout);

一旦你有了任何UB,任何事情都可能在任何时候发生。我将记录我看到的所有UB。你应该使用strncpy而不是strcpy,因为你的缓冲区被绑定到256字节;对于scanf,同样的事情,使用“%256s”而不是“%s”“.j的价值是什么?”当你说:当我试图在我的Ubuntu 15.04上运行它时,它编译并运行得非常完美。之所以发生这种情况,是因为您像gcc program.c-o程序那样编译。在你学得更好之前,你应该试试这个:gcc-Wextra-Werror-Wstrict prototype-Wconversion-std=c11-O2 program.c-o program@Snaipe几乎没有理由使用
strncpy
strncmp
。如果您不知道缓冲区的大小是否足够好,则说明您做错了什么。