代码在我的系统上运行良好,但是当我将它提交给应该检查它的机器人时会导致堆栈粉碎错误

Posted

技术标签:

【中文标题】代码在我的系统上运行良好,但是当我将它提交给应该检查它的机器人时会导致堆栈粉碎错误【英文标题】:Code works fine on my system but causes a stack smashing error when i submit it to the bot that is supposed to check it 【发布时间】:2020-04-17 22:30:39 【问题描述】:

这个阶段的这个程序应该从用户那里获取文本并将其分成段落、句子和单词。到目前为止,该代码在我的系统(ubuntu 18.04)上运行良好,但是当我将其提交给应该为其提供输入的机器人时,会出现堆栈粉碎错误。有没有办法让我的代码读取输入而不崩溃?

编辑: 这是一个测试输入。我认为问题在于它一次读取所有内容。(除了 ap 之外还有一些其他选项:我还没有制作):

测试 3 输入:ap:小说的中心是典型的 Graham Greene 角色。[ ]fw:h[ ]fs:ovel[ ]fp:typical[ ]owf[ ]owl[ ]ap:他累了 和怀疑,基本上体面但愤世嫉俗。一种感觉 生活对他来说没有真正的色彩,事实上它让他厌烦,然而 有一些救赎的潜在希望,一些 [ ]fw:or[ ]fw:is[ ] owf[ ]owl[ ]qt

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

void ap(char ***p, char ***s, char ***w, int *n_p, int *n_s, int *n_w)

    char *temp = malloc(10001 * sizeof(char));
    int i, k, j, length;

    if(temp == NULL)
    
        printf("Could not allocate memory");
        return;
    
    fgets(temp, 10001, stdin);
    while(temp[0] == ' ')
        for(i = 0;i < strlen(temp);i++)
            temp[i] = temp[i + 1];

    //paragraphs
    *n_p += 1;
    **p = realloc(**p, *n_p * sizeof(char *));
    *(*p + *n_p - 1) = malloc((strlen(temp) + 1) * sizeof(char));
    if(**p == NULL || *(*p + *n_p - 1) == NULL)
    
        printf("Could not allocate memory");
        return;
    
    strcpy(*(*p + *n_p - 1), temp);

    //sentences
    while(temp[0] != '\0')
    
        k = strcspn(temp, ".!?;");
        length = strlen(temp);
        temp[k] = '\0';
        *n_s += 1;
        **s = realloc(**s, *n_s * sizeof(char *));
        *(*s + *n_s - 1) = malloc((strlen(temp) + 1) * sizeof(char));
        if(**s == NULL || *(*s + *n_s - 1) == NULL)
        
            printf("Could not allocate memory");
            return;
        
        strcpy(*(*s + *n_s - 1), temp);
        j = 0;
        for(i = k + 1;j <= length - k;i++)
        
            temp[j] = temp[i];
            j++;
        
        while(temp[0] == ' ')
            for(i = 0;i < strlen(temp);i++)
                temp[i] = temp[i + 1];
        k = strcspn(temp, "\n");
        while(temp[k + 1] == ' ')
            for(i = k;i < strlen(temp);i++)
                temp[i] == temp[i + 1];
        if(!(strcmp(*(*s + *n_s - 1), "\n")))
        
            free(*(*s + *n_s - 1));
            *n_s -= 1;
        
     


int main()

    char **paragraphs, **sentences, **words, option[5];
    int num_par = 0, num_sent = 0, num_words = 0, i;

    paragraphs = malloc(sizeof(char *));
    sentences = malloc(sizeof(char *));
    words = malloc(sizeof(char *));
    if(paragraphs == NULL || sentences == NULL || words == NULL)
    
        printf("Could not allocate memory");
        return 1;
    

    do
    
        scanf("%s", option);
        if(!(strcmp(option, "ap:")))
            ap(&paragraphs, &sentences, &words, &num_par, &num_sent, &num_words);
    
    while(strcmp(option, "qt"));

    //test
    for(i = 0;i < num_par;i++)
        printf("%s", paragraphs[i]);
    printf("-------------  %d\n", num_sent);
    for(i = 0;i < num_sent;i++)
        printf("%s\n", sentences[i]);

    return 0;

【问题讨论】:

调试的一部分是创建一个 MRR(Minimal Reproducable Example)。 您可以尝试自己通过 Valgrind 运行它,但如果不提供某种测试输入,这是不可重现的。 您知道在for(i = 0;i &lt; strlen(temp)...strlen 函数在每个 迭代中被调用,浪费了大量的CPU 周期? 这个循环什么时候结束? while(temp[0] == ' ')?如果条件为真,你会改变什么? 我昨天看到了这段代码。它被认为过于复杂并给出了建议。我没有看到任何这些建议。 【参考方案1】:

option 太小,行:

scanf("%s", option);

尝试将每一行读入一个 5 个字符的数组。超过 5 个字符的行会溢出数组,gcc 会用金丝雀捕捉它并杀死你以破坏堆栈。

如果您的本地编译器没有实现堆栈粉碎检测,它可能会运行。

char option[x] 增加到适合您的行长的某个合理的 x 值。

【讨论】:

以上是关于代码在我的系统上运行良好,但是当我将它提交给应该检查它的机器人时会导致堆栈粉碎错误的主要内容,如果未能解决你的问题,请参考以下文章

.BLADE.PHP 在我的 LARAVEL 项目中不起作用。 .PHP 在我看来运行良好

jQuery插件可以在localhost上运行,但在我将它发布到服务器时则不行

代码在本地与服务器上执行不同

运行 xampp 的问题

应用程序在我的设备上运行,但当我将其发布到 Google Play 商店进行 Beta 测试时无法运行

找不到脚本函数 doget,但我没有在我的代码上使用 doGet