#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: 参照を、このときどうつかっていいのかわかりません。
ピクルス さんが書きました: ↑3年前
C++の質問です。
というプログラムを書いたところ、 a のみしか表示されません。#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; }
参照の&だけ使えば解決できるらしいのですが、この場合どこにも&が入れられる場所がないように思えます。
どのようにすれば、このプログラムはきちんと動くのでしょうか。
Re: 参照を、このときどうつかっていいのかわかりません。
#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/ で確認。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
Re: 参照を、このときどうつかっていいのかわかりません。
コンパイルエラーになりました。
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
ピクルス さんが書きました: ↑3年前どのようにすれば、このプログラムはきちんと動くのでしょうか。
- 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;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)