質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

829閲覧

【C言語】ディープコピーの方法について

decman

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2023/01/08 11:37

編集2023/01/08 11:52

実現したいこと

以下のソースでAにBをディープコピー?
(ポインタの先の内容をコピー)したいのですが、
うまくいっていません。
bstringCopy()内で実装できるディープコピーの手法を
ご教授いただけませんでしょうか。

発生している問題・エラーメッセージ

Segmentation fault(コアダンプ)

該当のソースコード

C

1test.h 2typedef struct tagbstring* bstring; 3 4struct tagbstring { 5 int mlen; 6 int slen; 7 unsigned char* data; 8} 9 10 11test.c 12 13#include <stdio.h> 14#include "test.h" 15#include <string.h> 16#include <stdlib.h> 17 18void bstringCopy(bstring dst, bstring src){ 19 dst->mlen = src->mlen; 20 dst->slen = src->slen; 21 22 size_t byte = sizeof(char); 23 size_t size = byte * strlen(src->data) + byte; 24 dst->data = malloc(size); 25 strcpy(dst->data, src->data); 26 27 return; 28} 29 30int main(){ 31 bstring a; 32 bstring b; 33 34 bstringCopy(a, b); 35 36 return 0; 37}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2023/01/08 12:36

提示のコードでどういう不具合があるんでしょうか。 そして、それをどう言う風にしたいんでしょう。
guest

回答3

0

C

1#include <string.h> 2#include <stdlib.h> 3#include <stdio.h> 4 5typedef struct tagbstring* bstring; 6 7struct tagbstring { 8 int mlen; 9 int slen; 10 unsigned char* data; 11}; 12 13bstring bstringMake(int m, int s, const char* d) { 14 bstring tmp = malloc(sizeof(struct tagbstring)); 15 if ( tmp != NULL ) { 16 char* str = malloc(strlen(d)+1); 17 if ( str == NULL ) { 18 free(tmp); 19 tmp = NULL; 20 } else { 21 strcpy(str, d); 22 tmp->data = str; 23 tmp->mlen = m; 24 tmp->slen = s; 25 } 26 } 27 return tmp; 28} 29 30void bstringDestroy(bstring b) { 31 free(b->data); 32 free(b); 33} 34 35void bstringCopy(bstring dst, bstring src){ 36 dst->mlen = src->mlen; 37 dst->slen = src->slen; 38 39 size_t byte = sizeof(char); 40 size_t size = byte * strlen(src->data) + byte; 41 dst->data = malloc(size); 42 free(dst->data); 43 strcpy(dst->data, src->data); 44 45 return; 46} 47 48int main(){ 49 bstring a = bstringMake(123, 456, "Hello, World"); 50 bstring b = bstringMake(0, 0, ""); 51 52 bstringCopy(b, a); 53 54 printf("a: data = [%s] mlen=%d slen=%d\n", a->data, a->mlen, a->slen); 55 printf("b: data = [%s] mlen=%d slen=%d\n", b->data, b->mlen, b->slen); 56 57 bstringDestroy(a); 58 bstringDestroy(b); 59 return 0; 60}

投稿2023/01/09 13:33

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

deep copy以前の段階で間違っています。

typedef struct tagbstring* bstring;
としているのですから、bstring型の変数は構造体へのポインタです。ですから
bstring a;
bstring b;
のaやbもポインタです。そのポインタを初期化(何かを明示的に指すようにすること)もなくポインタが指す先にアクセスする行為は未定義ですが、多くの場合アクセス違反(Segmentation fault)を引き起こすもので、実際そうなったという話です。
当然ながら、tagbstringのメンバー変数のポインタ(data)も適切な初期化が行われた後でなければそのポイント先にアクセスしてはいけません。

deep copyの処理自体は間違っているとまでは言いませんが、
・sizeof(char)はsizeofの動作の定義から必ず1です。

JISX3010
6.5.3.4 sizeof演算子  
(略)
型char,unsigned char若しくはsigned char(又はそれらの修飾版)をもつオペランドに適用した場合の結果は,1とする。

・mallocに失敗する可能性は0ではない、とするのがお作法です。そして、mallocに失敗したら適宜処理(といっても強制終了するぐらいしか手はないことが多いでしょうが)すぺきです。

というあたりに検討の余地があると思います。

投稿2023/01/08 13:08

thkana

総合スコア7639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2023/01/08 13:13

うげ、なんかアイコンがあひるちゃんに入れ替わってる...(治るんだろうなぁ) おっと、コメントに気がついてなかった。 > ローカル変数a,bには値が入っているものだという認識でお願いいたします。 ちゃんと値が入っていればsegmentation faultにはならないはずなので、その認識は無理です。 それと、全体に影響のある追記は質問本文にも行ってください。
thkana

2023/01/08 13:15

(アイコンの入れ替わりはブラウザ変えたらでない...firefoxダメ?)
y_waiwai

2023/01/08 13:23

ちょっと前から、アイコンが入れ替わったり、ベストアンサーの赤色が別のところにつく、って不具合が発生してますねー 困ったもんです
ikadzuchi

2023/01/09 08:45

最近見かける気がするこの不具合、前からあったのかと気になっていましたが、やっぱり最近でいいんですね。 1年経ってまだ着々と破壊が進んでいるんですねえ。
guest

0

そもそも、ローカル変数で定義したものは中身はデタラメです
それをコピーしようとすることが間違いです

投稿2023/01/08 12:38

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

decman

2023/01/08 12:55

回答ありがとうございます。 すみません、記載が漏れておりましたが、ローカル変数a,bには 値が入っているものだという認識でお願いいたします。
y_waiwai

2023/01/08 13:02

提示のコードではどういう不具合があるんでしょうか
decman

2023/01/08 13:08

不具合といいますか、そもそもディープコピーの手法がイマイチ理解できていないので、 この書き方で合っているかもわかっておりません。。 なので、この構造体の場合におけるディープコピーの方法を お教えいただければと思っております。。
y_waiwai

2023/01/08 13:12

なら、それぞれの変数での値の代入からの実際に動作するコードを書いてみてください。 そのコードさえないので、答えようがないです
jimbe

2023/01/11 09:29

『ディープコピーの手法』なんて、ただ必要なコピーをするというだけですけど…なにか試験問題のように、ディープコピーの正解があると考えているのでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問