0

在在线编译器上,这个程序在给出输入时给出了完美的输出"ABACABA",但在 Codeforces 测试中它只是发布了最后一行。在调试时,我发现指针u指示使用0strstr()的地址。我无法理解为什么该函数可以在其他在线编译器上运行,但不能在 Codeforces 上运行。

编辑:好的,多亏了@Jeremy Friesner,我发现实际上是 strncpy 无法正常工作,因为现在自定义测试用例编译器为“str”提供了错误的输出。仍然不知道为什么它在两个不同的编译器上的行为会有所不同,以及我应该进行哪些更改。

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<stdlib.h>
using namespace std;


int main()
{
    char *s;
    int length=20;
    s = (char *) malloc(length*(sizeof(char)));
    char c;
    int count=0;
    while((c=getchar())>='A')
    {
        if(c<='Z')
        {
           //cout<<count;
           if(length>=count)
           {
               s = (char *) realloc(s,(length+=10)*sizeof(char));
           }
           s[count++]=c;    
           //printf("%p\n",s);

        }
        else
        {
            break;
        }
   }
   char *u=s;
   int o=1;
   //printf("%p\n",s);
   while(u)
   {
       char *str = (char *) malloc(o*sizeof(char));
       str = strncpy(str,s,o);
       //cout<<str<<endl;
       char *t;
       u = strstr(s+1,str);
       //printf("u %p\n",u);
       t=u;
       int ct=0;
       char *p;
       while(t)
       {  
           ct++;
           p=t;
           t = strstr(t+o,str); 
       }

       ct=ct+1;
       //cout<<"here"<<endl;
       if(p==(s+count-o))
       {
           cout<<o<<" "<<ct<<endl;
       }
       //cout<<ct<<endl;
       o++;

   }
   cout<<count<<" "<<1;
}
4

2 回答 2

1

如评论中所述,一个主要问题是您在读入字符串后没有以空值终止字符串,这会导致奇怪的结果。具体来说,它会导致您调用未定义的行为,这总是一件坏事。分配的内存malloc()和分配的额外内存realloc()不保证归零。

您可以通过添加以下内容来解决问题:

s[count] = '\0';

就在之前:

char *u = s;

malloc()严格来说,您还应该检查和的返回值realloc()。此外,你不应该使用成语:

x = realloc(x, newsize);

如果realloc()失败,您就丢失了指向原始数据的指针,因此您已经泄漏了内存。安全的工作方式是:

void *space = realloc(x, newsize);
if (space == 0)
    …report error etc…
x = space;
x_size = newsize;

可能还有其他问题;我没有仔细检查所有可能问题的代码。

于 2014-05-23T05:14:55.757 回答
1

您永远不会在您放入的字符之后放置空终止符s,因此s不包含字符串。因此,它会导致未定义的行为将其传递给需要字符串的函数,例如strncpy.

另一个大问题是您对strncpy.

int o=1;

while(u)
{
   char *str = (char *) malloc(o*sizeof(char));
   str = strncpy(str,s,o);
   u = strstr(s+1,str);

strncpy函数不创建字符串,如果strlen(s) >= o. 在这种情况下,该strstr函数只会读取缓冲区的末尾,从而导致未定义的行为。(究竟会发生什么将取决于您的编译器以及这段内存中的垃圾)。

您需要将一个以空字符结尾的字符串放入str. 手动添加一个空终止符:

assert(o > 0);
strncpy(str, s, o-1);
str[o-1] = 0;

或使用不同的功能:

snprintf(str, o, "%s", s);

您必须记住,字符串是一系列字符,后跟一个空终止符。每当您使用需要字符串的函数时,由您决定是否存在空终止符。

还要小心像strstr(t+o,str);. 如果o > strlen(t)这导致未定义的行为。你必须自己检查你没有超出字符串的范围。

于 2014-05-23T01:33:50.487 回答