在C中超过了内存限制

在C中超过了内存限制,c,C,我目前是一名C语言的学生的导师。在他的课程中,学校安装了一个运行(能够接收代码并测试代码的软件)的服务器 在发送到服务器之前,我们已经开发了代码,编译并在本地进行了测试,一切都很顺利。但是,当我们试图将其发送到服务器时,服务器声明“内存限制已超出” 代码如下所示: #include <stdio.h> #include <stdlib.h> #include <math.h> #include <limits.h> #include <str

我目前是一名C语言的学生的导师。在他的课程中,学校安装了一个运行(能够接收代码并测试代码的软件)的服务器

在发送到服务器之前,我们已经开发了代码,编译并在本地进行了测试,一切都很顺利。但是,当我们试图将其发送到服务器时,服务器声明“内存限制已超出”

代码如下所示:

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

#define LIMITE_CARACTERES 1000
#define LIMITE_GENES 100000

char genes[LIMITE_GENES][LIMITE_CARACTERES];

char* copiar_por_espaco(char* string, char* dest)
{
    for(int i = 0; i < strlen(string); i++)
    {
        if(' ' == string[i])
        {
            strncpy(dest, string, i);
            dest[i] ='\0';
            if( i + 1 >= strlen(string))
                return NULL;
            else
                return &string[i+1];
        }
    }
    if(strlen(string) == 0)
    {
        return NULL;
    }
    else
    {
        strcpy(dest, string);
        return NULL;
    }
}


void genes_f()
{
    char s[LIMITE_CARACTERES];
    int numero_genes = 0;
    while(scanf("%s", s) != EOF)
    {
        char *auxiliar = s;
        while(auxiliar != NULL && strlen(auxiliar) != 0)
        {
            auxiliar = copiar_por_espaco(auxiliar, genes[numero_genes]);
            numero_genes++;
        }
    }
    if(numero_genes <= 20)
    {
        for(int i = 0; i < numero_genes; i++)
        {
            printf("%s\n", genes[i]);
        }
    }
    else
    {
        for(int i = 0; i < 10; i++)
        {
            printf("%s\n", genes[i]);
        }

        for(int i = numero_genes - 10; i < numero_genes;i++)
        {
            printf("%s\n", genes[i]);
        }
    }
}


int main()
{
    genes_f();
    return 0;
}
输出
既然你是一名家庭教师,我会给出反馈,这样你就可以正确地教你的学生(所以这不是你问题的答案)

espaco副总裁

for(int i = 0; i < strlen(string); i++)
请注意,可以保证字符串不包含空格,因为它是使用
scanf
读取的。因此,函数将始终返回
NULL

if(strlen(string) == 0) return NULL;
您可以在循环之后进行测试,但逻辑指示您在任何处理之前进行测试,如果(!*string)返回NULL,则可以将其缩短为
这也会使代码更漂亮,因为不需要
else
部分(反正也不需要)

基因

while(scanf("%s", s) != EOF)
scanf专家可能会在这方面有所帮助,但我相信格式说明符中必须有空格,这样它将跳过前导空格,
“%s”
。我相信您的方法将只读取一个字符串,然后在每次
scanf
调用中无限循环返回零。您应该测试scanf的结果,以确定成功转换的格式说明符的数量,而不是EOF。因此,检查
1

if(numero_genes <= 20)

if(numero\u genes您忘记在数组中包含空终止符的额外字节。如果
LIMITE\u CARACTERES
是作为输入提供的字符串的最大长度,则需要一个大小为
LIMITE\u CARACTERES+1
的数组来存储它。因此需要更改此行

char genes[LIMITE_GENES][LIMITE_CARACTERES];


与您的错误没有直接关系,但是您可以完全删除
for
循环,因为
if
的条件总是
false
。由于
字符串
来自
scanf
,采用
%s
格式,因此可以保证其中不会有空格。我同意@StoryTeller。尝试铸造e> strlen
到int:
for(int i=0;i<(int)strlen(string);i++)
即使在实际“超过时间限制”的情况下,它也可能显示“超出内存限制”?使用大型局部变量时最有可能出现堆栈溢出。作为补充说明,您不应该教学生以下错误做法:使用英语以外的另一种语言编码,出于任何目的使用strncpy,使用20世纪80年代的“yoda条件”编码风格、编写非复合语句的语句、从单个函数返回多个意大利面等等@Lundin我认为这与堆栈大小无关:我只看到堆栈分配
char s[1000]
,这还不足以触发堆栈溢出。你好,Paul,我已经向我的学生说明了所有这些问题,但是scanf可以读取空格(至少我们用空格测试了它,它成功了)。此解决方案不是由我提出的,而是由我的学生提出的。目前,该级别的优化将不会得到关注,因为该学生还有其他应优先考虑的困难。此外,根据编码,scanf存在数组边界漏洞。如果键入的非空格字符超过1000个,您将写入数组行的末尾。@RicardoAlves,
scanf
%s
的定义是“字符串,直到第一个空格字符(空格、制表符或换行符)。@PaulOgilvie是的,您可以使用。您需要在页面底部选择两个级别的版本。即
#定义str(s)#s
#定义fmt(x)%“str x”s
@PaulOgilvie只需定义您可以读取的字符数,并使用该数字+1的存储定义数组,例如,
char genes[LIMITE_genes][LIMITE_CARACTERES+1];//+1为\0添加空间
确实这是一个我们已经忘记的问题,谢谢您指出。不过,我认为这不是问题所在。
if(strlen(string) == 0) return NULL;
while(scanf("%s", s) != EOF)
if(numero_genes <= 20)
    for(int i = numero_genes; i < numero_genes; i++)
        printf("%s\n", genes[i]);
numero_genes<LIMITE_GENES
char genes[LIMITE_GENES][LIMITE_CARACTERES];
char genes[LIMITE_GENES][LIMITE_CARACTERES + 1];