前提・実現したいこと
C言語初心者です。
指定ファイル内を探索してディレクトリ・ファイル名を出力するシステムを作成しています。
現状ブレークポイントが発生しました。と出ますがCSV出力されている状態です。
また出力の際正常に対象全てのデータが出力されることもあれば途中まで出力されることもあります。
(Sample2やSample4で終わったりしています。)
検索してみるとヒープが破壊されていることが原因なのかなと考えているのですが
どのように修正すればよいか分からないといった状況です。
よろしくお願いいたします。
発生している問題・エラーメッセージ
例外が発生しました。 file_search.exe によってブレークポイントが発生しました。
該当のソースコード
Sampleファイル https://gyazo.com/c8e4387bf035c97eeb96ad42b844f837 呼び出し履歴 https://gyazo.com/936af4fdc360b075db5ccbcc9a031a44 ブレークポイント発生箇所(exe_common.inl) https://gyazo.com/1ab31c3a03fc8af1fb0fa9a2524ec853
C
1main.c 2#define _CRT_SECURE_NO_WARNINGS 3 4#include <Windows.h> 5#include <stdio.h> 6#include <locale.h> 7#include <stdlib.h> 8#include <io.h> 9#include <sys/stat.h> 10#include <direct.h> 11#include <string.h> 12#include <wchar.h> 13#include <limits.h> 14 15void FileSearch(const wchar_t* dirpath, int count); 16char file_name[1024]; 17const char output_dir[1024]; 18FILE* file; 19 20int main(int argc, char* argv[]) 21{ 22 // 絶対パスの分割と取得 23 char* search_file = argv[1]; 24 25 char path_dir[1024] = { '\0' }; 26 char* dirend; 27 28 dirend = strrchr(search_file, '\'); 29 dirend = dirend + 1; 30 31 for (int n = 0; n < (int)strlen(search_file); n++) 32 { 33 path_dir[n] = search_file[n]; 34 if (search_file + n == dirend - 1) 35 { 36 break; 37 } 38 } 39 40 // パスの変数化 41 sprintf(file_name, "%sOutput/output.csv", path_dir); 42 sprintf(output_dir, "%sOutput", path_dir); 43 strcat(path_dir, dirend); 44 sprintf(path_dir,"%s\\", path_dir); 45 46 //システム既定のロケールに設定する 47 setlocale(LC_ALL, ""); 48 //マルチバイト文字をワイド文字に変換 49 wchar_t* wide_path_dir[1024]; 50 mbstowcs(wide_path_dir, path_dir, sizeof(wide_path_dir) / sizeof(wide_path_dir[0])); 51 52 if (argc > 1) 53 { 54 // Outputディレクトリがデスクトップに存在するか確認 55 struct stat output; 56 int existence = stat(output_dir, &output); 57 // Outputディレクトリがなかった時作成する 58 if (existence != 0) 59 { 60 (void)_mkdir(output_dir); 61 } 62 63 file = fopen(file_name, "w"); 64 fprintf(file, "%s\n", dirend); 65 fclose(file); 66 } 67 68 // ディレクトリ名とファイル名、ファイルサイズを表示する 69 FileSearch(wide_path_dir, 1); 70 return 0; 71} 72 73 74// 引数として渡したディレクトリ以下のディレクトリとファイルを全て表示する 75void FileSearch(const wchar_t* dirpath, int count) 76{ 77 78 long long int size = 0; 79 int i = 0; 80 int datasize = 0; 81 int pathsize = 0; 82 83 // ハンドル 84 HANDLE hFind; 85 // ファイル情報 86 WIN32_FIND_DATA win32fd; 87 88 datasize = sizeof(win32fd); 89 90 // ディレクトリにワイルドカードを追加 91 // ファイル名も含んだパス 92 wchar_t* dirwildpath; 93 dirwildpath = (wchar_t*)malloc(sizeof(wchar_t) * datasize); 94 // ファイルパスをコピー 95 wcscpy(dirwildpath, dirpath); 96 // ワイルドカードを追加 97 wcscat(dirwildpath, L"*"); 98 99 // ハンドルを取得しファイル情報を保存する 100 hFind = FindFirstFile(dirwildpath, &win32fd); 101 102 // 何も見つからなかったとき 103 if (hFind == INVALID_HANDLE_VALUE) { 104 FindClose(hFind); 105 return; 106 } 107 free(dirwildpath); 108 while (FindNextFile(hFind, &win32fd)) 109 { 110 // カレントディレクトリと親ディレクトリのときは何もしない 111 if (wcscmp(win32fd.cFileName, L".") == 0 112 || wcscmp(win32fd.cFileName, L"..") == 0 || wcscmp(win32fd.cFileName, L"desktop.ini") == 0) 113 { 114 continue; 115 } 116 117 // ディレクトリのときの処理 118 else if (win32fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) 119 { 120 file = fopen(file_name, "a"); 121 for (i = 0; i < count; i++) 122 { 123 fprintf(file, ","); 124 } 125 fwprintf(file, L"%ls\n", win32fd.cFileName); 126 fclose(file); 127 128 // 文字列バッファを更新 129 pathsize = sizeof(dirpath); 130 wchar_t* dir_buf = (wchar_t*)malloc(sizeof(wchar_t) * pathsize); 131 /*if (count > 1) 132 { 133 free(dir_buf[count - 1]); 134 }*/ 135 136 // ディレクトリをコピーする 137 wcscpy(dir_buf, dirpath); 138 wcscat(dir_buf, win32fd.cFileName); 139 wcscat(dir_buf, L"\"); 140 // 再帰する 141 FileSearch(dir_buf, count + 1); 142 } 143 else 144 { 145 // ファイルのとき 146 file = fopen(file_name, "a"); 147 long long int fsize = fseek(file, 0, SEEK_END); 148 fgetpos(file, &size); 149 fseek(file, fsize, SEEK_SET); 150 for (i = 0; i < count; i++) 151 { 152 fprintf(file, ","); 153 } 154 fwprintf(file, L"%ls,%lld[byte]\n", win32fd.cFileName, size); 155 fclose(file); 156 } 157 } 158 FindClose(hFind); 159} 160 161
試したこと
動的配列のdirwildpathをFindClose(hFind)の前で解放してみたが変化なし
dir_bufはどのタイミングで解放していいか分かりません。
補足情報(FW/ツールのバージョンなど)
Windows10
Microsoft Visual C++ 2019
不足情報あれば随時追加させていただきます。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/11 02:53
2021/05/11 03:01
2021/05/11 03:10