• ベストアンサー

文字列クラスを作りたいと思っています。-2

文字列クラスを作りたいと思っています。 以下のようなところまでは作れましたが、 エラーがでてしまいます。 どこかおかしいところがあるのでしょうか? ********************************************** #include<stdio.h> #include<string.h> #include<conio.h> class stt { public: char *str; int len; bool maked; stt::stt() { len=0; str=NULL; maked=false; } stt::~stt() { delete[] str; } stt &operator =(char *c) { if(maked) { delete[] str; maked=false; } len=strlen(c); str=new char[len+1]; strcpy(str,c); maked=true; return (*this); } stt &operator =(stt &ste) { if(maked) { delete[] str; maked=false; } len=strlen(ste.str); str=new char[len+1]; strcpy(str,ste.str); maked=true; return (*this); } stt operator +(stt ste) { static stt tet; int len1=strlen(str); int len2=strlen(ste.str); tet.str=new char[len1+len2+2]; strcpy(tet.str,str); strcat(tet.str,ste.str); tet.str[len1+len2+1]='\0'; return tet; } virtual operator char*() { return str; } }; int main() { stt ss,ww,pp; pp="Hello"; ss="Nice to meet you.\n"; ww="I am studing Visual C++"; pp=ss+ww; printf(pp); getchar(); return 0; } **********************************************

質問者が選んだベストアンサー

  • ベストアンサー
noname#9119
noname#9119
回答No.2

operator+(stt ste) が値渡しなので、この関数から抜けるときに ste のデストラクタが呼ばれる。 そして operator+() の戻り値が stt なので、pp に代入された後この戻り値の stt のデストラクタが呼ばれる。 そしてあとあとで str メンバが指すメモリ領域が delete されているのにまた delete しようとしてエラーになる。

thulala
質問者

お礼

ありがとうございました。

thulala
質問者

補足

ありがとうございます。 どことなくですが、わかりました。 その辺りを勉強したいのですが、 参考書籍はご存知でしょうか? また、No3の方のいうコピーコンストラクタの こともよくわかりませんでした。 それについての、 参考書籍も教えていただきたいです。

その他の回答 (2)

回答No.3

static stt tet; が原因ではないと思いますが、 コピーコンストラクタを作れば解決すると思います stt::stt(stt& stt2) { len = 0; str = NULL; maked = false; *this = stt2; } こんな感じです

thulala
質問者

お礼

ありがとうございます。 補足欄に書いたことですが、 一度コンストラクタが呼び出されたときに、makedがfalseからtrueに変更され、二度目の呼び出しで delete[]strが実行されるという形にしました。 実際は、思ったとおりに動作しているか不安です。 makedが全てfalseでデストラクタ内で扱われているような気がします。

thulala
質問者

補足

これで、いいでしょうか? stt::~stt() { if(maked) { delete[] str; } else { maked=true; } } stt operator +(stt ste) { static stt tet; int len1=strlen(str); int len2=strlen(ste.str); tet.str=new char[len1+len2+2]; strcpy(tet.str,str); strcat(tet.str,ste.str); tet.str[len1+len2+1]='\0'; ste.maked=false; return tet; }

回答No.1

どこでエラーが発生しているのでしょうか? そしてどういったエラーが出ているのでしょうか?

thulala
質問者

補足

stt operator +(stt ste){}内部で宣言した static stt tet;が、エラーの原因と思います。 tetのデストラクタで、delete[] str;しようとしたとき、 アドレスが不明か、なにかはわかりません。 エラーは、 Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) です。 対処法があれば、教えてください。 お願いします。

関連するQ&A

  • operator +()について

    --------------------------------------- 文字列クラスを作りたいと思っています。 以下のようなところまでは作れましたが、 全てのstrをdelete[] str;しているのかわかりません。 delete[] str;を確認するにはどうすればいいですか? --------------------------------------- #include<stdio.h> #include<string.h> #include<conio.h> class stt { public: char *str; int len; bool maked; stt::stt() { len=0; str=NULL; maked=false; } stt::~stt()// ちゃんとデストラクタ内で、全てのstrがdeleteされているのでしょうか? { if(maked) { delete[] str; } else { maked=true; } } stt &operator =(char *c) { if(maked) { delete[] str; maked=false; } len=strlen(c); str=new char[len+1]; strcpy(str,c); maked=true; return (*this); } stt &operator =(stt &ste) { if(maked) { delete[] str; maked=false; } len=strlen(ste.str); str=new char[len+1]; strcpy(str,ste.str); maked=true; return (*this); } stt operator +(stt ste) { stt tet; int len1=strlen(str); int len2=strlen(ste.str); tet.str=new char[len1+len2+2]; strcpy(tet.str,str); strcat(tet.str,ste.str); tet.str[len1+len2+1]='\0'; ste.maked=false;//不安部分 return tet; } virtual operator char*() { return str; } }; int main() { stt ss,ww,pp; ss="a"; ww="b"; pp=ss+ww; printf(pp); printf("\n"); getchar(); return 0; }

  • 文字列クラスを作りたいと思っています

    文字列クラスを作りたいと思っています。 以下のようなところまでは作れましたが、 エラーがでてしまいます。 どこかおかしいところがあるのでしょうか? *********************************************** #include<stdio.h> #include<string.h> class stt { public: char *str; int len; bool maked; stt::stt() { len=0; str=NULL; maked=false; } stt::~stt() { delete[] str; } stt &operator =(char *c) { if(maked) { delete[] str; maked=false; } len=strlen(c); str=new char[len]; strcpy(str,c); maked=true; return (*this); } virtual operator char*() { return str; } }; int main() { stt s; s="Hello World"; printf(s); getchar(); return 0; } ***********************************************

  • 文字列の扱い方

    初歩的な質問ですみません… str文字列からcという文字を見つけたら添字を返すという関数を作ったのですが、 iにこの関数を代入して、if文の制御式にiを使って比較するまでは正常なのですが、 真文にiを使うと何故か偽文(という言い方でいいのでしょうか…この場合("そんな値はありません。"というところです)が実行されてしまいます。 よろしければご教授お願い致します。 #include <stdio.h> int str_char(const char str[],int c) { int len = strlen(str); int i; for (i = 0;i < len;i++) { if (str[i] == c) return i; } return -1; } int main() { char str[64] = "Fucking Brutal Death Metal"; int ch,i; printf("どの文字を調べますか?"); scanf("%c",&ch); i = str_char(str,ch); if (i >= 0) printf("その文字は%d番目にあります。",str_char(str,ch) + 1); //何故かiだと動かない else printf("そんな値はありません。"); return 0; }

  • 文字列に関する関数

    現在C言語の勉強をしております。 そこで、以下の関数の作成について質問させてください。 【関数の仕様】 引数の文字列から、'-'(ハイフン)と'P'以降を排除した文字列を返す。 自分なりに作成してみたのですが、コンパイルで警告が出てしまう状況です・・・。 もっとスマートに書けるんだろうとは思っているんですが、精一杯でした・・・。 どなたか教えていただけませんでしょうか? char *getDelStr(char *str) { int len = strlen(str); int count; char targetStr[32]; for(count = 0; count < len; count++){ if(str[count] != 'P'){ if(str[count] != '-'){ strcat(targetStr,str[count]); } }else{ return targetStr; } } return str; } 以上、よろしくお願いいたします。

  • C++のoperator関数でのキャストする場合の書き方がまだよく理解

    C++のoperator関数でのキャストする場合の書き方がまだよく理解できていません。 下記のコードで、 //ここから #include "stdafx.h" #include <string> #include <iostream> class AutoPtr { char *ptr; public: AutoPtr():ptr(0) { } ~AutoPtr() { delete [] ptr; } // char *operator=(char *ptr) { delete [] this->ptr; this->ptr = ptr; return this->ptr; } operator char *(){ return ptr; } char &operator[](int index) { return ptr[index]; } }; void reverse(char *str) { int i, n; AutoPtr work; n = strlen(str); work = new char[n+1]; strcpy(work, str); for(i=0; i<n; i++) { str[i] = work[n-i-1]; } printf("%s\n", str); } int _tmain(int argc, _TCHAR* argv[]) { char str[] = "ABCDEFG"; reverse(str); return 0; } //ここまで 2番目のoperator関数の定義ですが、 operator char *(){ return ptr; } これは多分、reverse()関数中の、 strcpy(work, str); のworkの展開に用いられると思うのですが、 機能としては、「operator char *」はAutoPtrをchar *にキャストするために使われているらしいのですが、何故この書き方でAutoPtrをchar *型にキャストできるのかがいまいち分かりません。また、2番目のoperator関数の記述「operator char *()」はどこまでが型で、どこからが関数の定義と見なせばよいのでしょうか? 何か勘違いしているかもしれません。理解されている方、御教示いただければと思っています。 よろしくお願い致します。

  • 文字列の扱いについて教えてください

    #include<cstdio> #include<cstring> #define _CRT_SECURE_NO_DEPRECATE 1 #define MAXBUFF 256 void s_swap(char* str_a, char* str_b) { char str_dummy[MAXBUFF]; strcpy_s(str_dummy,strlen(str_dummy),str_a); ★ strcpy_s(str_a,strlen(str_a),str_b); ★ strcpy_s(str_b,strlen(str_b),str_dummy); } void main(void) { char* str_a = "ABC"; char* str_b = "DEF"; int a; printf("呼出前:str_a=%s, str_b=%s\n", str_a, str_b); s_swap(str_a,str_b); printf("呼出後:str_a=%s, str_b=%s\n", str_a, str_b); } str_aとstr_bの中身を入れ替える処理で、エラーや警告はでないのですが ★のところで実行失敗します。 昔から文字列の処理は苦手でどのように攻略したらよいのか 解説していただけないでしょうか。

  • C++のコンストラクタを使った自動ポインタでoperator関数の使い

    C++のコンストラクタを使った自動ポインタでoperator関数の使い方で分からないところがあります。 環境下はVisual C++でC/C++のWin32コンソールアプリケーションを使って行っています。 下記のコードで実行させています。やっていることは文字列を反転させて表示させるだけのことです。 #include "stdafx.h" #include <string> #include <iostream> class AutoPtr { char *ptr; public: AutoPtr():ptr(0) { } ~AutoPtr() { delete [] ptr; } // char *operator=(char *ptr) { delete [] this->ptr; this->ptr = ptr; return this->ptr; } operator char *(){ return ptr; } char &operator[](int index) { return ptr[index]; } }; void reverse(char *str) { int i, n; AutoPtr work; n = strlen(str); work = new char[n+1]; strcpy(work, str); for(i=0; i<n; i++) { str[i] = work[n-i-1]; } printf("%s\n", str); } int _tmain(int argc, _TCHAR* argv[]) { reverse("ABCDEFG"); return 0; } これを実行させると、reverse関数のfor()文の、str[i] = work[n-i-1];を実行させた所で実行エラーになってしまいます。その前の、strcpy(work, str);でworkにstrの内容が正常にコピーされているところまでは確認できています。operator関数の、 char &operator[](int index) { return ptr[index]; } で、operator[]はAutoPtrを配列のように扱っているはずなのですが、何故かstr[i] = work[n-i-1]; の所で実行エラーになってしまいます。 operaror関数の書き方が悪いのか、何が原因なのか分かりかねています。御経験のあるかたは、御教示いただけたらと思っています。 よろしくお願い致します。

  • 全角文字と半角文字を判別して文字列を追加

    全角文字と半角文字が混合している文字列に文字を追加するプログラムを考えています。 仕様としては全角から半角に変わる際には全角文字の後ろに1234を、 半角から全角に変わるときは半角文字の後ろに4321をつけるというものです。 例1 文字列が「あxxxお」ならば出力結果は「あ1234xxx4321お」 そこで質問なのですが 文字列から全角文字と半角文字をプログラム上で判別して 上記のように出力するにはどうしたらいいんでしょうか? ヒント等ございましたらどうぞお願いします。 とりあえず作ってみた例1の結果を無理やり出力するプログラムのコードを載せておきます。 こちらをうまく改変してくださっても結構ですのでよろしくお願いいたします。 #include <stdio.h> #include <string.h> int main(void){ unsigned char str0[256] = "あxxxお", str1[256] = "1234",str2[256]= "4321"; unsigned int zh,hz, len0 = strlen(str0),len1=strlen(str1),len2=strlen(str2); printf("挿入前:%s\n",&str0); zh=2; //全角から半角に変わる位置 hz=5; //半角から全角に変わる位置 //1234を挿入/// memmove(&str0[zh+len1], &str0[zh], len0 - zh+1); memcpy(&str0[zh], str1, len1); //4321を挿入/// memmove(&str0[hz+len1+len2], &str0[hz+len1], len0); memcpy(&str0[hz+len1], str2, len2); printf("挿入後:%s\n",&str0); return 0; }

  • 文字列

    下のプログラムは何をするためのプログラムなのか教えてください。 個人的にはJISコードに関係していると思うのですがさっぱりわかりません。 どなたか詳しい説明お願いします。 #include <stdio.h> #define LEN 255 int main(void) { char str[LEN]; char cipher[LEN]; int ikey; int i,n; printf("文字列を入力せよ : "); scanf("%s", str); printf("鍵を入力 : "); scanf("%d", &ikey); i = 0; while (str[i]!='\0') { n = (str[i]-'A'+ikey)%26; cipher[i] = 'A'+n; ++i; } cipher[i] = '\0'; printf("%s\n", cipher); return 0; }

  • const 回りのエラー?

    以下のプログラムをcygiwn 上でコンパイルすると エラーが出るのですが 何がいけないのかよくわかりません。 メッセージを読んでconst 回りなのかな?とは思っているのですが… よろしくお願いします。 #include<iostream> #include<cstring> #include<cstdlib> using namespace std; class sample{ char *s; public: sample(); sample(const sample &ob); ~sample(){if(s) delete [] s; cout << "Freeing s\n";} void show(){cout << s << "\n";} void set(char *str); sample operator=(sample &ob); }; sample::sample() { s = new char('\0'); if(!s){ cout << "Allocation error\n"; exit(1); } } sample::sample(const sample &ob) { s = new char[strlen(ob.s)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } strcpy(s,ob.s); } void sample::set(char *str) { s = new char[strlen(str)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } strcpy(s,str); } sample sample::operator=(sample &ob) { if(strlen(ob.s)>strlen(s)){ delete [] s; s = new char[strlen(ob.s)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } } strcpy(s,ob.s); return *this; } sample input() { char instr[80]; sample str; cout << "Enter a string: "; cin >> instr; str.set(instr); return str; } int main() { sample ob; ob = input(); ob.show(); return 0; } <コンパイル結果> In function 'int main()': 78:error:no match for 'operator=' in 'ob = input()()' 49:note:candidates are: sample sample::operator=(sample&)

専門家に質問してみよう