gcc 6.3.0
質問です。
呼び出された時に、要素数nの配列を確保して破棄しない(static付けた時のように)関数を作りたいんですけど、以下のようにすると、
error: storage size of 'a' isn't constant
サイズが不明でエラーになるみたいです。
任意のサイズとタイミングで確保できれば、別に関数である必要はないのですが、
なんとかこれを実装する方法はありますか。
任意のタイミング,サイズで配列を作る方法
Re: 任意のタイミング,サイズで配列を作る方法
malloc (C言語) だとか,
new とか STL (C++言語) とか,
そういう方向の話ですか?
new とか STL (C++言語) とか,
そういう方向の話ですか?
Re: 任意のタイミング,サイズで配列を作る方法
回答ありがとうございます。
すみません、あまり知識がないので、これがそういう方向の話なのか分かりません・・・
「メモリを動的に確保する」感じの話ではあると思います。
Cを使いたいので、mallocが使えそうだったので使ってみました。
無事コンパイル通りました。ありがとうございます。
しかし、なんだか大げさな感じがしてしまいます。
何と言えばいいか分かりませんが、もうすこし質素な、
ヘッダファイルが要らないようなやり方で、どうにかする方法はないのでしょうか。
すみません、あまり知識がないので、これがそういう方向の話なのか分かりません・・・
「メモリを動的に確保する」感じの話ではあると思います。
Cを使いたいので、mallocが使えそうだったので使ってみました。
#include <stdlib.h>
void main(){return;}
void f (int n)
{
static int* a;
a = (int*)malloc(sizeof(int)*n);
free(a);
return;
}
しかし、なんだか大げさな感じがしてしまいます。
何と言えばいいか分かりませんが、もうすこし質素な、
ヘッダファイルが要らないようなやり方で、どうにかする方法はないのでしょうか。
Re: 任意のタイミング,サイズで配列を作る方法
staticでなくてよければ、gcc拡張、もしくはC99の仕様で可変長配列(VLA : Variable-Length Array)が使えます。
【追記】
すいません、質問をよく読んでいませんでした。
「確保して解放しない」というのが条件なのですね。
すいません、質問をよく読んでいませんでした。
「確保して解放しない」というのが条件なのですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 任意のタイミング,サイズで配列を作る方法
どうしてそのようなことがしたいのですか? (The XY Problemの疑いがあります)
このプログラムは、この質問の回答としては間違っています。
free(a);にとり、せっかく確保した配列が破棄されてしまいます。
とすると、free(a);により前に確保した配列を破棄し(メモリリーク防止)、新しい配列を残すことができます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 任意のタイミング,サイズで配列を作る方法
Windows 10 PRO(64bit)
visual studio 2019
mikufree.cpp
出力
8<---------------------------
Detected memory leaks!
Dumping objects ->
C:\Users\MrAtassyu\Documents\2020x02\2019H31-01-01Atassyxx86\CBDxlibUnilove0Cuda-2020R02-12-19\MikuFree\MikuFree\MikuFree.cpp(18) : {90} normal block at 0x00B27CF8, 0 bytes long.
Data: <> -P{]Øîþÿÿÿùo
Object dump complete.
8<---------------------------
やっぱ、static int* a; を free(a); しちゃ、まずいだろ。
visual studio 2019
mikufree.cpp
#include <stdlib.h>
//
// https://urashita.com/archives/1271
// Visual Studio C++でメモリリークの検出
// crtdbg.h CrtSetDbgFlag C言語のアクセス違反の調査 | urashita.com 浦下.com(ウラシタドットコム)(ja)
//
#include <crtdbg.h>
#define malloc(X) _malloc_dbg(X,_NORMAL_BLOCK, __FILE__,__LINE__)
#define new ::new(_NORMAL_BLOCK, __FILE__,__LINE__ )
//
//
//
void
f(int n)
{
static int* a;
free(a);
a = (int*)malloc(sizeof(int) * n);
return;
}
int
main()
{
_CrtSetDbgFlag(
_CRTDBG_ALLOC_MEM_DF
| _CRTDBG_DELAY_FREE_MEM_DF
| _CRTDBG_CHECK_ALWAYS_DF
| _CRTDBG_LEAK_CHECK_DF
);
f(0);
return EXIT_SUCCESS;
}
// end.
8<---------------------------
Detected memory leaks!
Dumping objects ->
C:\Users\MrAtassyu\Documents\2020x02\2019H31-01-01Atassyxx86\CBDxlibUnilove0Cuda-2020R02-12-19\MikuFree\MikuFree\MikuFree.cpp(18) : {90} normal block at 0x00B27CF8, 0 bytes long.
Data: <> -P{]Øîþÿÿÿùo
Object dump complete.
8<---------------------------
やっぱ、static int* a; を free(a); しちゃ、まずいだろ。
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: 任意のタイミング,サイズで配列を作る方法
みけCATさん、
回答ありがとうございます
この構造体が次回呼び出し時まで値を保持しておく必要は無く、
ただ単に確保と破棄を繰り返すのが、「基本グローバル変数しか存在しないような言語」を触っていたせいで気持ち悪かっただけで、
呼び出しのたびに確保する形でも良かったのかも知れません。
確かに、問題は私の思い込みや設計だと思います。
それらを他人に教えて貰う方法について心当たりがなく、c言語の問題まで自分で絞って質問しました。
よく考えず質問してしまいすみませんでした。
回答して頂きありがとうございました。精進します!
確保直後に解放してたのは、何考えてたんでしょうね・・・多分解放してないのが怖かったんだと思います。
サンプルまで添えて頂き、ありがとうございます。
あたっしゅさん、
私にはなにやらよく分かりませんが、みけCATさんのサンプルに問題がある感じですか。
回答ありがとうございます
質問を受けて、長々とやりたいことを書き綴って整理しておりましたら、今気づきました。どうしてそのようなことをしたいのですか?
この構造体が次回呼び出し時まで値を保持しておく必要は無く、
ただ単に確保と破棄を繰り返すのが、「基本グローバル変数しか存在しないような言語」を触っていたせいで気持ち悪かっただけで、
呼び出しのたびに確保する形でも良かったのかも知れません。
確かに、問題は私の思い込みや設計だと思います。
それらを他人に教えて貰う方法について心当たりがなく、c言語の問題まで自分で絞って質問しました。
よく考えず質問してしまいすみませんでした。
回答して頂きありがとうございました。精進します!
確保直後に解放してたのは、何考えてたんでしょうね・・・多分解放してないのが怖かったんだと思います。
サンプルまで添えて頂き、ありがとうございます。
あたっしゅさん、
私にはなにやらよく分かりませんが、みけCATさんのサンプルに問題がある感じですか。
Re: 任意のタイミング,サイズで配列を作る方法
> 私にはなにやらよく分かりませんが、みけCATさんのサンプルに問題がある感じですか。
そうです。
そうです。
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: 任意のタイミング,サイズで配列を作る方法
static int* a;はヌルポインタに初期化され、
freeにヌルポインタを渡した場合は何もしないと決まっているので、問題ないはずです。
また、#6ではmallocに0を渡しているようですが、malloc(0)が何を返すかは処理系定義です。
#6の例では、malloc(0)はヌルポインタではないポインタを返すタイプの処理系であり、
その返されたポインタをfreeしていないため、メモリリークの発生として検出されているようですね。
以下、N1570より引用
6.7.9 Initialization
7.22.3.3 The free functionIf an object that has static or thread storage duration is not initialized
explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
J.3 Implementation-defined behaviorIf ptr is a null pointer, no action occurs.
J.3.12 Library functions
7.22.3 Memory management functionsWhether the calloc, malloc, and realloc functions return a null pointer or a
pointer to an allocated object when the size requested is zero (7.22.3).
If the size of
the space requested is zero, the behavior is implementation-defined: either a null pointer
is returned, or the behavior is as if the size were some nonzero value, except that the
returned pointer shall not be used to access an object.
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)