hageking
@hageking

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

c++のuuidについて

Q&A

Closed

解決したいこと

c++でuuidを返す関数を作りたいです。

該当するソースコード

#include <iostream>
#include <uuid/uuid.h>

void uuid(char *data)
{
	const int uuid_len = 36 + 1; // 36byte string + null
	uuid_t u1;
	char out[uuid_len];
	uuid_generate(u1);
	uuid_unparse(u1, out);
	data = out;
}

int main(void)
{
	char a[37] = "7C23E045-F7A0-41C8-A1E7-5C5A1C027EF1";
	uuid(a);
	std::cout << a;
	return 0;
}

結果

7C23E045-F7A0-41C8-A1E7-5C5A1C027EF1

自分で試したこと

uuid関数内のout変数とdata変数にはuuidが入っていますがmain関数のaには代入されてません。
どうしたら良いですか?
解決方法を教えてください。

0

2Answer

uuid()の引数dataはchar型のポインタです。
つまり、a[37]の配列の先頭のアドレスが代入されています。

対して、uuid()の末尾で

data = out;

と代入しています。
これは data に対して out[uuid_len] の先頭アドレスを代入しています。
つまり、直前まで保持していたa[37]の先頭アドレスを見失うことになります。

そして、uuid()からmain()に戻ると、a[37]の内容には何も変化がありませんからuuid()での処理は何も反映されません。

uuid()で行うべきことはdataが指し示すアドレス以下にoutの内容をコピーすることです。
ということで、strncpy()を使ってoutの内容をdataにコピーすれば良いのではないでしょうか?

0Like

Comments

  1. @hageking

    Questioner

    回答ありがとうございます。
    strncpy()を使って解決できました。

@shigeokamoto さんの説明どおり
data = out;

strncpy(data, out, uuid_len);
に入れ替えしてからは行けると思います。

この問題は以下のC言語の概念と関連しています。

・有効範囲
outがuuidという関数の中に定義されているため、基本的にその関数の内部にのみ有効
※実はdataも

・関数のパラメータで渡されているものは、本物の参照か、本物のコピーか
uuidのパラメータ(char *data)がコピーで、aという配列とほぼ平等なものですが、実は別もので、指している文字列がaと同じだけです。
このため、関数の内部でdata=outにしても、更新されるのは内部のdataだけで、外にあるaに影響しません。
strncpyを使うことで、dataが指している文字列(即ちaがさしている文字列)を更新して、outが関数の外部で無効になるにもかかわらず、関数の内部でoutの内容を用いて外部で定義されているaを更新したので、関数終了した後もaの更新が残ります。

0Like

Comments

  1. @hageking

    Questioner

    回答ありがとうございます。
    なんでstrncpyを使ってできるのかがわかりませんでしたがPirloさんの意見でわかりました。
    ありがとうございます。

Your answer might help someone💌