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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

1478閲覧

メモリリークの対処法を聞きたいです。

kaful

総合スコア2

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/07/26 02:27

編集2021/07/26 03:25

前提・実現したいこと

メモリリークの対処法を聞きたい。

ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

今現在Pythonを学んでいる学生です。
質問内容は円を作成し、動かすオブジェクトを作っているのですが前のオブジェクトを削除する方法を教えてほしいです。
学習本を読み、オブジェクトを適当な変数に保存し、新しいオブジェクトを作る前にdeleteで削除するという対応を調べたのですが、どの部分にデリートを挿入するのかなどが記載されていなかったため質問いたしました。

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

円を一つ作成して動かす(動かす処理は前の円を白にして見え無くし、消したように見せているだけです)だけなら問題ないのですが複数の円を作成し動かすとメモリリークが発生しプログラムがうまく動きません。

該当のソースコード

python

1ball=[{"x":400,"y":300,"dx":1,"dy":1,"color":"red"}, 2 {"x":200,"y":100,"dx":-1,"dy":1,"color":"green"}, 3 {"x":100,"y":200,"dx":1,"dy":-1,"color":"blue"} 4 ] 5 6円を動かす処理ですballに入っているリストの数だけ円を作成しています。 7def move(): 8 global ball 9 for b in ball: 10 11 canvas.create_oval(b["x"]-20,b["y"]-20,b["x"]+20,b["y"]+20,fill="white",width=0) 12 13 b["x"]=b["x"]+b["dx"] 14 b["y"]=b["y"]+b["dy"] 15 16 canvas.create_oval(b["x"]-20,b["y"]-20,b["x"]+20,b["y"]+20,fill=b["color"],width=0) 17 18 if b["x"]>=canvas.winfo_width(): 19 b["dx"]=-1 20 if b["x"]<=0: 21 b["dx"]=1 22 if b["y"]>=canvas.winfo_height(): 23 b["dy"]=-1 24 if b["y"]<=0: 25 b["dy"]=1 26 27 28 root.after(10,move)
Python

試したこと

学習本を読んだ。ネットで検索したがいまいち理解できなかった。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

IDLEを使っています。pythonのバージョンは3.9です。

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

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

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

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

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

maisumakun

2021/07/26 02:32

> プログラムがうまく動きません。 具体的には、どういう状況になるのですか?
quickquip

2021/07/26 02:38

このコードは「うまく動きません」と言っているコードではなくて、うまく動いている方のコードではないでしょうか?
jbpb0

2021/07/26 03:15

pythonのコードの一番最初の行のすぐ上に ```python だけの行を追加してください また、pythonのコードの一番最後の行のすぐ下に ``` だけの行を追加してください 現状、コードがとても読み辛いです 質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
kaful

2021/07/26 03:20

>maisumakunさん 具体的にはエラーなどは出ないのですが、メモリが圧迫してうまく描画されていない状態になります。 >quickquipさん 申し訳ございません。間違えて記載していました。リストの中身を二つ以上にするとエラーというか動かなくなっていました。
guest

回答3

0

ベストアンサー

for b in ball: (略) root.after(10,move)

ですから、リストを3つにするとroot.after(10,move)が3回よばれます。
すると10ms後にmoveが3回呼ばれるんじゃないでしょうか? (詳しくないので自信はありません)

そうだとすると、次の10ms後に9回、次の10ms後に27回、、、、となっているのではないですか?

意図しているコードは

python

1def move(): 2 global ball 3 for b in ball: 4 canvas.create_oval(b["x"]-20,b["y"]-20,b["x"]+20,b["y"]+20,fill="white",width=0) 5 6 b["x"]=b["x"]+b["dx"] 7 b["y"]=b["y"]+b["dy"] 8 9 canvas.create_oval(b["x"]-20,b["y"]-20,b["x"]+20,b["y"]+20,fill=b["color"],width=0) 10 11 if b["x"]>=canvas.winfo_width(): 12 b["dx"]=-1 13 if b["x"]<=0: 14 b["dx"]=1 15 if b["y"]>=canvas.winfo_height(): 16 b["dy"]=-1 17 if b["y"]<=0: 18 b["dy"]=1 19 20 21 root.after(10,move)

ではないでしょうか?


(ついで)

python

1def move(): 2 for b in ball: 3 canvas.create_oval(b["x"]-20,b["y"]-20,b["x"]+20,b["y"]+20,fill="white",width=0) 4 5 for b in ball: 6 b["x"]=b["x"]+b["dx"] 7 b["y"]=b["y"]+b["dy"] 8 9 canvas.create_oval(b["x"]-20,b["y"]-20,b["x"]+20,b["y"]+20,fill=b["color"],width=0) 10 11 if b["x"]>=canvas.winfo_width(): 12 b["dx"]=-1 13 if b["x"]<=0: 14 b["dx"]=1 15 if b["y"]>=canvas.winfo_height(): 16 b["dy"]=-1 17 if b["y"]<=0: 18 b["dy"]=1 19 20 21 root.after(10,move)

の方がいい気はします。

投稿2021/07/26 04:22

編集2021/07/26 04:27
quickquip

総合スコア11235

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

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

kaful

2021/07/26 04:28

ありがとうございます。自分のコードでは指数関数的にmoveが行われてしまっていたという事でしょうか。 quickquipさんの通りにコードを書き換えた結果教科書と同様の動きをしてくれました。ありがとうございます。
quickquip

2021/07/26 04:31

コードを見て、そうなっているんだろうな、と想像しました。 修正して動いたのならそういうことで合っていたと思います。
guest

0

次のように、canvas.delete を使うようです。

キャンバスの図形の削除

投稿2021/07/26 04:07

Zuishin

総合スコア28669

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

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

Zuishin

2021/07/26 04:08

なおすべてクリアしたい時は delete('all') だそうです。
kaful

2021/07/26 04:10

ありがとうございます!クラスを使った方法はまだ試していなかったのでこれからやって確かめてみようと思います!
guest

0

そもそものはなしですが、

メモリリークが発生しプログラムがうまく動きません。

オブジェクトを生成して開放できないってのは、メモリリークとは言いません

投稿2021/07/26 02:44

y_waiwai

総合スコア88042

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

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

Zuishin

2021/07/26 03:18

解放しなかったらメモリリークするのでは?
y_waiwai

2021/07/26 03:21

それはただの開放忘れでは。 リークと言うからには、意図的な未開放は対象にはならないと思いますが
Zuishin

2021/07/26 03:32

メモリリークという言葉がどこかで定義されているわけでもないので私の解釈を述べるのはやめておきますが、要するに使用済みのオブジェクトを解放せず繰り返し処理を行っているためにメモリを使いすぎて足りなくなるので解放の仕方を教えてほしいという質問じゃないでしょうか。
Zuishin

2021/07/26 03:35

参考のため、leak にはこのような使い方があるということだけ書いておきます。 https://ejje.weblio.jp/content/leak > He leaked the news to the press. 彼は記者たちにそのニュースを漏らした.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問