参照を、このときどうつかっていいのかわかりません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ピクルス

参照を、このときどうつかっていいのかわかりません。

#1

投稿記事 by ピクルス » 3年前

#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: 参照を、このときどうつかっていいのかわかりません。

#2

投稿記事 by ピクルス » 3年前

ピクルス さんが書きました:
3年前

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 のみしか表示されません。
参照の&だけ使えば解決できるらしいのですが、この場合どこにも&が入れられる場所がないように思えます。
どのようにすれば、このプログラムはきちんと動くのでしょうか。

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: 参照を、このときどうつかっていいのかわかりません。

#3

投稿記事 by あたっしゅ » 3年前

コード:

#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, 電子ブロック 持ち。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 参照を、このときどうつかっていいのかわかりません。

#4

投稿記事 by みけCAT » 3年前

あたっしゅ さんが書きました:
3年前
とりあえず、元のプログラムをできるだけ残して、修正。
コンパイルエラーになりました。

コード:

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で殴ればいい!(死亡フラグ)

返信

“C言語何でも質問掲示板” へ戻る