gpt4 book ai didi

C++ - 一个函数会使其他函数发生故障

转载 作者:行者123 更新时间:2023-11-30 03:55:12 25 4
gpt4 key购买 nike

这是我的任务:

编写 Word 类,它具有:

  1. 字符数组指针
  2. 构造函数和析构函数
  3. 读词功能
  4. 函数检查作为参数传递给它的字符是否出现在单词中并返回出现的位置
  5. 检查两个单词中哪个单词出现次数为 10 的次数更多并返回出现次数的函数

这是我的解决方案。我编译它没有错误,但它不能正常工作。

#include <iostream>
#include <string.h>

using namespace std;

class Word
{
private:
char *content;
int length;
public:
Word();
Word(char *);
~Word();
void print_content(void);
int check_character(char);
friend int check_number(Word,Word);
};


Word::Word()
{
}

Word::Word(char *n)
{
length=strlen(n);
content=new char [length];
for(int i=0;i<length;i++)
{
content[i]=n[i];
}
}


Word::~Word()
{
delete content;
}


void Word::print_content(void)
{
for(int i=0;i<length;i++)
{
cout<<""<<content[i];
}
}


int Word::check_character(char a)
{
int position=0;
for(int i=0;i<length;i++)
{
if(content[i]==a)
{
position=i+1;
}
}
if(position>0)
{
return position;
}
else return 0;
}


int check_number(Word n,Word m)
{
int counter_n=0;
int counter_m=0;
for(int i=1;i<n.length;i++)
{
if((n.content[i-1]=='1')&&(n.content[i]=='0'))
{
counter_n=counter_n+1;
}
}
for(int i=1;i<m.length;i++)
{
if((m.content[i-1]=='1')&&(m.content[i]=='0'))
{
counter_m=counter_m+1;
}
}
if(counter_n>counter_m)
{
return counter_n;
}
else if(counter_n<counter_m)
{
return counter_m;
}
else return 0;
}


int main()
{
char characters1[]="qwerty10",*p1,*p2;
char characters2[]="stackoverflow101010";
p1=characters1;
p2=characters2;
Word first(p1);
Word second(p2);
cout<<""<<first.check_character('q')<<endl;
cout<<""<<second.check_character('f')<<endl;

//cout<<""<<check_number(first,second)<<endl;

first.print_content();
second.print_content();
}

函数 check_number(first,second) 由于某种原因使其他函数无法正常工作,如果您通过删除“//”来调用它,您将看到 first.print_content() 和 second.print_content() 不给我们正确的结果。或者,如果首先调用函数 first.check_character('r'),然后调用 second.check_character('j'),然后调用 check_number(first,second),则两个首先调用的函数将不起作用。这种奇怪行为的原因是什么?

最佳答案

Word 对象通过复制传递给 check_number,但您没有定义复制构造函数。所以编译器使用默认一个,这个复制指针(char* 内容)。传递给函数的临时对象指向在主函数中创建的数据 firstsecond...删除时(调用函数后删除临时对象),它们删除指针,因此 firstsecond 对象指向已删除的内存。您在这里有未确定的行为,这解释了您遇到的副作用。

通过引用 check_number 传递对象是解决问题的简单方法。这是一个工作代码(包括许多修复,因为您没有正确访问数组):

#include <iostream>
using namespace std;

#include <iostream>
#include <string.h>

using namespace std;

class Word
{
private:
char *content;
int length;
public:
Word();
Word(char *);
~Word();
void print_content(void);
int check_character(char);
friend int check_number(const Word&,const Word&); // changed here
};


Word::Word()
{
}

Word::Word(char *n)
{
length=strlen(n);
content=new char [length];
for(int i=0;i<length;i++)
{
content[i]=n[i]; // changed here
}
}


Word::~Word()
{
delete [] content; // changed here
}


void Word::print_content(void)
{
for(int i=0;i<length;i++)
{
cout<<""<<content[i]; // changed here
}
}


int Word::check_character(char a)
{
int position=0;
for(int i=0;i<length;i++)
{
if(content[i]==a) // changed here
{
position=i+1;
}
}
if(position>0)
{
return position;
}
else return 0;
}


int check_number( const Word& n, const Word& m)// changed here
{
int counter_n=0;
int counter_m=0;
for(int i=1;i<n.length;i++)
{
if((n.content[i-1]=='1')&&(n.content[i]=='0')) // changed here
{
counter_n=counter_n+1;
}
}
for(int i=1;i<m.length;i++)
{
if((m.content[i-1]=='1')&&(m.content[i]=='0')) // changed here
{
counter_m=counter_m+1;
}
}
if(counter_n>counter_m)
{
return counter_n;
}
else if(counter_n<counter_m)
{
return counter_m;
}
else return 0;
}


int main()
{
char characters1[]="qwerty10",*p1,*p2;
char characters2[]="stackoverflow101010";
p1=characters1;
p2=characters2;
Word first(p1);
Word second(p2);
cout<<""<<first.check_character('q')<<endl;
cout<<""<<second.check_character('f')<<endl;

cout<<""<<check_number(first,second)<<endl;

first.print_content();
second.print_content();
}

这个输出:

1
10
3
qwerty10stackoverflow101010

声明一个复制构造函数是另一种解决问题的方法:

Word( const Wodr& word ) :
length( word.length ),
content( new char[word.length] )
{
memcpy( content, word.content, word.length );
}

这比通过 const 引用传递对象效率低,但会使您的代码更安全(最好始终声明复制构造函数以防止您在此处遇到的错误)。

最后,如果你比较懒,也可以将拷贝构造函数声明为private,防止编译器拷贝对象,只声明,不要强制:

class Word
{
....
private:
Word( const Word& word ); // this makes argument passed by copy impossible.
};

然后,编译器不会让你调用 check_number。

关于C++ - 一个函数会使其他函数发生故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29182871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com