ページ 1 / 1
参照を、このときどうつかっていいのかわかりません。
Posted: 2020年10月23日(金) 03:15
by ピクルス
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include<cstdlib>
using namespace std;
class samp {
char *s;
public:
samp() { cout << "a"; s = '\0'; }
~samp() { if (s) free(s); cout << "sを開放する\n"; }
void show() { cout << s << "\n"; }
void set(char* str);
};
void samp::set(char* str) {
s = (char*)malloc(strlen(str) + 1);
if (!s) {
cout << "メモリ割り当てエラー\n";
exit(1);
}
strcpy(s, str);
}
samp input() {
char s[80];
samp str;
cout << "文字列の入力: ";
cin >> *s;
str.set(s);
return str;
}
int main()
{
samp ob;
ob = input();
ob.show();
return 0;
}
というプログラムを書いたところ、 a のみしか表示されません。
参照の&だけ使えば解決できるらしいのですが、この場合どこにも&が入れられる場所がないように思えます。
どのようにすれば、このプログラムはきちんと動くのでしょうか。
Re: 参照を、このときどうつかっていいのかわかりません。
Posted: 2020年10月23日(金) 03:18
by ピクルス
ピクルス さんが書きました: ↑4年前
C++の質問です。
コード:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include<cstdlib>
using namespace std;
class samp {
char *s;
public:
samp() { cout << "a"; s = '\0'; }
~samp() { if (s) free(s); cout << "sを開放する\n"; }
void show() { cout << s << "\n"; }
void set(char* str);
};
void samp::set(char* str) {
s = (char*)malloc(strlen(str) + 1);
if (!s) {
cout << "メモリ割り当てエラー\n";
exit(1);
}
strcpy(s, str);
}
samp input() {
char s[80];
samp str;
cout << "文字列の入力: ";
cin >> *s;
str.set(s);
return str;
}
int main()
{
samp ob;
ob = input();
ob.show();
return 0;
}
というプログラムを書いたところ、 a のみしか表示されません。
参照の&だけ使えば解決できるらしいのですが、この場合どこにも&が入れられる場所がないように思えます。
どのようにすれば、このプログラムはきちんと動くのでしょうか。
Re: 参照を、このときどうつかっていいのかわかりません。
Posted: 2020年10月23日(金) 08:31
by あたっしゅ
コード:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include<cstdlib>
using namespace std;
class samp {
char *s;
public:
samp() { cout << "a"; s = '\0'; }
~samp() { if (s) free(s); cout << "sを開放する\n"; }
void show() { cout << s << "\n"; }
void set(char* str);
};
void samp::set(char* str) {
cout << __LINE__ << ":" << str << endl;
s = (char*)malloc(strlen(str) + 1);
if (!s) {
cout << "メモリ割り当てエラー\n";
exit(1);
}
strcpy(s, str);
}
void input( samp& ob ) {
char s[80];
cout << "文字列の入力: ";
cin >> s;
cout << __LINE__ << ":" << s << endl;
ob.set(s);
}
int main()
{
samp ob;
input( ob );
ob.show();
return 0;
}
// end.
とりあえず、元のプログラムをできるだけ残して、修正。
https://www.onlinegdb.com/ で確認。
Re: 参照を、このときどうつかっていいのかわかりません。
Posted: 2020年10月23日(金) 22:01
by みけCAT
あたっしゅ さんが書きました: ↑4年前
とりあえず、元のプログラムをできるだけ残して、修正。
コンパイルエラーになりました。
コード:
prog.cc: In constructor 'samp::samp()':
prog.cc:12:31: error: invalid conversion from 'char' to 'char*' [-fpermissive]
12 | samp() { cout << "a"; s = '\0'; }
| ^~~~
| |
| char
ピクルス さんが書きました: ↑4年前
どのようにすれば、このプログラムはきちんと動くのでしょうか。
- samp::sはポインタなので、文字'\0'ではなくポインタを代入するようにする
- sampのコピーによりポインタがコピーされ、二重開放などの問題の原因になるのを防ぐため、
内容をコピーするためのコピーコンストラクタと代入演算子を定義する(The Rule of Three)
- input関数内でsをデリファレンスするのをやめ、文字ではなく文字列を入力するようにする
コード:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include<cstdlib>
using namespace std;
class samp {
char *s;
public:
samp() { cout << "a"; s = NULL; }
samp(const samp& sa) {
s = NULL;
if (sa.s != NULL) set(sa.s);
}
~samp() { if (s) free(s); cout << "sを開放する\n"; }
samp& operator=(const samp& sa) {
if (&sa != this) {
free(s);
s = NULL;
if (sa.s != NULL) set(sa.s);
}
return *this;
}
void show() { cout << s << "\n"; }
void set(char* str);
};
void samp::set(char* str) {
s = (char*)malloc(strlen(str) + 1);
if (!s) {
cout << "メモリ割り当てエラー\n";
exit(1);
}
strcpy(s, str);
}
samp input() {
char s[80];
samp str;
cout << "文字列の入力: ";
cin >> s;
str.set(s);
return str;
}
int main()
{
samp ob;
ob = input();
ob.show();
return 0;
}