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

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

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

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

Q&A

解決済

2回答

536閲覧

C言語で動的メモリ確保を行う際,大体550MBを超えたあたりからreallocがエラーを吐く

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2017/07/29 13:33

C言語で以下のようなコードを書いております。

C

1 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#include <malloc.h> 6#define malloc_usable_size(a) _msize(a) 7 8/** 9 * @param int c 10 * @param char*[] 11 * @return int 12 */ 13int main (int c, char* param[]) { 14 15 16 char * open_file_path; 17 char* new_file_path; 18 if (c >= 3) { 19 open_file_path = param[1]; 20 new_file_path = param[2]; 21 } else { 22 printf("You need to input three parameter from console."); 23 exit(2); 24 } 25 int read_byte; 26 int read_count = 1; 27 int *ip = NULL; 28 char* save = NULL; 29 char* buffer = NULL; 30 char* return_c = NULL; 31 char* temp = NULL; 32 FILE* fp = NULL; 33 34 // ファイルの読み込みサイズは1MBに設定 35 read_byte = sizeof(char) * 1000000; 36 buffer = (char*) malloc (read_byte); 37 if (buffer == NULL) { 38 printf("This command failed to secure appropriate memory allocation."); 39 exit(2); 40 } 41 fp = fopen(open_file_path, "rb"); 42 int i = 1; // ファイルサイズ 43 int current_address = 0; 44 int res; 45 46 while(1) { 47 // ファイルの読み込み 48 res = fread(buffer, read_byte, read_count, fp); 49 if (res >= read_count) { 50 // ここで初めてメモリの動的確保 51 if (i == 1) { 52 // 初回のみ 53 temp = (char*)malloc(read_byte * i); 54 save = temp; 55 printf("\r\n"); 56 printf("%d", read_byte * i); 57 memmove(save + current_address, buffer, read_byte); 58 // 現在のアドレスの位置を保持 59 current_address = current_address + read_byte; 60 printf("1"); 61 } else { 62 temp = (char*)realloc((void*)save, read_byte * i); 63 printf("2"); 64 if (temp != NULL) { 65 if (save == temp) { 66 printf("\r\n"); 67 printf("Two addresses has same memory address."); 68 save = temp; 69 70 } else { 71 printf("\r\n"); 72 printf("Two addresses has different memory address."); 73 save = temp; 74 } 75 printf("\r\n"); 76 printf("%d", read_byte * i); 77 memmove(save + current_address, buffer, read_byte); 78 // 現在のアドレスの位置を保持 79 current_address = current_address + read_byte; 80 } else { 81 printf("You cannot get memory you commanded."); 82 printf("%d", read_byte); 83 exit(2); 84 } 85 } 86 } else { 87 break; 88 } 89 i++; 90 } 91 fclose(fp); 92 FILE* new_fp = NULL; 93 new_fp = fopen(new_file_path, "wb+"); 94 fwrite(save, _msize(save), read_count, new_fp); 95 fclose(new_fp); 96 exit(1); 97}

上記のコードは実行時の第一コマンドライン引数をコピーし,第二コマンドライン引数のファイル名を作成し
まるっと移す処理です。
実行したところファイル容量が大体550MBを超える動画ファイルなどのコピーを実行すると
途中でrealloc関数が必ずエラーになってしまいす。

このメモリ確保時のエラーについて回避する方法はないでしょうか?

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

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

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

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

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

guest

回答2

0

OSは各ソフトウェアに対し、あまり大量の連続したメモリーは提供できません。

もちろんChironianさんがすでに指摘しているように動画をまるまるメモリーにロードするとかいう暴挙は慎まれるべきですが、そこまで行かずとも、大量の連続したメモリーは空き容量があっても確保に失敗することを念頭においてください。空き容量があるかと確保できるかは別問題です。

つまりC++でいうならstd::dequeのようなデータ構造(小規模なメモリー空間へのポインタ配列)をつかうべきです。

投稿2017/07/29 14:48

編集2017/07/29 14:49
yumetodo

総合スコア5850

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

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

0

ベストアンサー

こんにちは。

動画ファイル等をコピーするのに、それを一度全てメモリへ読み込むのは止めるべきと思います。メモリが安い現在でも贅沢すぎるメモリの使い方ではないでしょうか?

ファイルI/OはHDDのアクセス単位に丸めた方が多少なりと効率が良いです。512バイトの2のべき乗倍のどこかが適切なサイズですので1024*1024バイト単位くらいで読み出して書き込みすれば良いと思います。

投稿2017/07/29 14:02

Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2017/07/29 14:14

確かに,ふと思って常用しているPHPで同様のファイルのコピーを行ってみたところ, 断続的にファイル容量が増えていったので,Chironianさんのおっしゃる通り適度な容量で追記していく方がいいのですね・・・。 てっきりCはなんでもできるという幻想持っていたので何の躊躇もなくreallocしていました。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問