简体   繁体   English

C++ 程序中的分段错误查找重复字符串中的字符

[英]Segmentation fault in a C++ program finding occurrence of a character in repeated string

Following code counts total occurrence of a character,'a' in string,s repeated upto n number of characters:以下代码计算字符串中字符“a”的总出现次数,最多重复 n 个字符:

#include<iostream>
using namespace std;

long repeatedString(string s, long n) 
{
    long count=0,i;
    char *s1{ new char[n]{} };
    int j=0;
    for(i=0;i<n;i++)
    {
        s1[i]=s[j++];
        if(j==s.size())
            j=0;
    }

    for(i=0;i<n;i++)
    {
        if(s1[i]=='a')
            count++;
    }
    return count;

}

int main()
{
   string s = "abaca";
   long n = 12;
   cout<<repeatedString(s,n);
   return 0;
}

It runs fine with following input:它运行良好,输入如下:

Eg.例如。 Here s is " abaca ", s1 will be " abacaabacaab " so n gets calculated to 7.这里s是“ abaca ”, s1将是“ abacaabacaab ”,所以n被计算为 7。

But if s is " a " and n is 1000000000000 , it gets aborted due to bad_alloc但是如果s是 " a " 并且n1000000000000 ,它会因为 bad_alloc 而中止

Can anyone help me solve this issue?谁能帮我解决这个问题?

Thanks in advance!提前致谢!

We start with s1.size() == 0 and for a string s1[i] is invalid for any value of i greater or equal to s1.size() .我们从s1.size() == 0开始,对于字符串s1[i]对于任何大于或等于s1.size()i值都是无效的。 In this case it is always invalid.在这种情况下,它总是无效的。

Change s1[i]=s[j++];改变s1[i]=s[j++]; to s1 +=s [j++];s1 +=s [j++];

The object s1 of the type std::string is empty std::string 类型的 object s1 为空

string s1="";

So you may not use the subscript operator to change it所以你可能不会使用下标运算符来改变它

    s1[i]=s[j++];

You could declare the object like您可以像这样声明 object

string s1( n, ' ' );

In this case it contains n elements that can be changed using the subscript operator.在这种情况下,它包含可以使用下标运算符更改的 n 个元素。

Another approach is to use the operator +=.另一种方法是使用运算符 +=。 For example例如

string s1;
s1.reserve( n );

//...

s1 += s[j++]; s1 += s[j++];

Pay attention to that the value 1000000000000 of the parameter n can be too big and the system will be unable to allocate such a string.注意参数n的值1000000000000可能太大,系统将无法分配这样的字符串。

In this case you have to check whether the system is able to allocate enough elements for the object.在这种情况下,您必须检查系统是否能够为 object 分配足够的元素。

For example例如

string s1;

if ( not ( n < s1.max_size() ) ) n = s1.max_size();
s1.reserve( n );

and then接着

s1 += s[j++]; s1 += s[j++];

Pay attention to that the return type of the function should be at least size_t but it will be even better to use std::string::size_type .注意 function 的返回类型至少应该是size_t但使用std::string::size_type会更好。

Here is a demonstrative program这是一个演示程序

#include <iostream>
#include <string>

std::string::size_type repeatedString( const std::string &s, std::string::size_type n ) 
{
    std::string s1;

    if ( not( n < s1.max_size() ) ) n = s1.max_size();

    s1.reserve( n );

    for ( std::string::size_type i = 0, j = 0; i < n; i++ )
    {
        s1 += s[j++];

        if ( j == s.size() ) j = 0;
    }

    std::string::size_type count = 0;

    for ( const auto &c : s1 )
    {
        if ( c == 'a' ) ++count;
    }

    return count;
}

int main() 
{
    std::string s( "abaca" );

    std::string::size_type n = 12;

    std::cout << repeatedString( s, n ) << '\n';

    return 0;
}

Its output is它的 output 是

7

Instead of the range-based for loop in the function而不是 function 中基于范围的 for 循环

    for ( const auto &c : s1 )
    {
        if ( c == 'a' ) ++count;
    }

you could use the standard algorithm std::count declared in the header <algorithm> .您可以使用在 header <algorithm>中声明的标准算法std::count

If the system is unable to allocate a string of a given size then it throws an exception of the type std::bad_alloc .如果系统无法分配给定大小的字符串,则会抛出std::bad_alloc类型的异常。 You can catch the exception.您可以捕获异常。

In this case the function can look the following way as it is shown in the demonstrative program.在这种情况下,function 可以如下所示,如演示程序中所示。

#include <iostream>
#include <string>

std::string::size_type repeatedString( const std::string &s, 
                                       std::string::size_type n ) throw( std::bad_alloc ) 
{
    std::string s1;

    if ( not( n < s1.max_size() - 1 ) ) n = s1.max_size() - 1;

    s1.reserve( n );

    return n;

    for ( std::string::size_type i = 0, j = 0; i < n; i++ )
    {
        s1 += s[j++];

        if ( j == s.size() ) j = 0;
    }

    std::string::size_type count = 0;

    for ( const auto &c : s1 )
    {
        if ( c == 'a' ) ++count;
    }

    return count;
}

int main() 
{
    std::string s( "a" );

    std::string::size_type n = 1000000000000;

    try
    {
        std::cout << repeatedString( s, n ) << '\n';
    }
    catch ( const std::bad_alloc & )
    {
        std::cout << n << " is too big value.\n";
    }

    return 0;
}

The program output might look like程序 output 可能看起来像

1000000000000 is too big value.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM