PDA

View Full Version : مبتدی: به دست آوردن محتویات یک فولدر



ehsan_faal
دوشنبه 22 تیر 1394, 10:35 صبح
سلام.
من نیاز داشتم تا محتویات یکی از فولدرهام رو داشته باشم.کد زیر رو نوشتم که وقتی توی محیط IDE هستم کار میکنه ولی وقتی به تنهایی فایل exe رو اجرا میکنم با یک appCrash مواجه میشم.
میخواستم ببینم اشکالی توی این کد وجود داره؟
(در ضمن QtCreator استفاده میکنم و برنامه های دیگه ای که توی این IDE نوشتم مشکل ندارن واجرا میشن(مسیر کامپایلر minGW و فلدر bin رو به path اضافه کردم)).

#include <iostream>
#include <iomanip>
#include <dirent.h>
#include <vector>
#include <string>
#include <memory>
#include <fstream>
using namespace std;

vector<string> getContent(const string& path)
{
unique_ptr<DIR> dir(opendir(path.c_str()));
unique_ptr<dirent> pdir;
vector<string> files;
while ((pdir=unique_ptr<dirent>(readdir(dir.get())))) {
files.push_back(pdir->d_name);
}
return files;
}

int main()
{
vector<string> Content(getContent("C:/Users/Ehsan/Downloads/Packages"));
Content.erase(Content.begin(),Content.begin()+2);
ofstream result("C:/Users/Ehsan/Desktop/LaTex_Packages_List.txt");
if (result.is_open())
{
auto index=1;
for(auto& item: Content)
result<<setw(5)<<setiosflags(ios::left)<<(index++)<<": "<<item<<endl;
}
else
{
cout << "Error opening file";
}

return 0;
}


در ضمن یه سوال دومی هم داشتم توی خط 23 خروجی تابع به صورت اتوماتیک move میشه یا باید خودم با دستور move کامپایلر رو ملزم به استفاده از move constructor کنم؟

با تشکر

متن ارور:


Problem signature:
Problem Event Name: APPCRASH
Application Name: QtConsole.exe
Application Version: 0.0.0.0
Application Timestamp: 00000000
Fault Module Name: ntdll.dll
Fault Module Version: 6.3.9600.17668
Fault Module Timestamp: 54c846bb
Exception Code: c0000005
Exception Offset: 00042249
OS Version: 6.3.9600.2.0.0.768.101
Locale ID: 1033
Additional Information 1: 5861
Additional Information 2: 5861822e1919d7c014bbb064c64908b2
Additional Information 3: a10f
Additional Information 4: a10ff7d2bb2516fdc753f9c34fc3b069

Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=280262

If the online privacy statement is not available, please read our privacy statement offline:
C:\Windows\system32\en-US\erofflps.txt

rahnema1
دوشنبه 22 تیر 1394, 15:44 عصر
سلام
استفاده از unique_ptr در اینجا درست نیست
از کتابخانه هایی که استفاده می شه لازمه مستندات اون به خوبی مطالعه بشه مثل همین کتابخانه c که در اینجا برای خواندن دیرکتوری استفاده شده.
وقتی opendir کردیم در مقابل تابع closedir وجود داره ممکنه opendir فضایی از حافظه را رزرو کنه اما کارهای دیگه هم ممکنه بکنه که فقط با closedir ین کار خاتمه پیدا می کنه نه اینکه اتوماتیک حافظه رزرو شده را با unique_ptr باز پس بدیم
همچنین توی مستندات گفته حافظه ای که توسط readdir رزور می شه را هیچ وقت نباید free کرد چون خود کتابخانه c فکر این کار را هم کرده. اما دوباره با unique_ptr این کار انجام می شه
حالا یه چند نکته در مورد باز کردن فایلها که لازمه وقتی فایلی باز شد یا مثلا حافظه ای اشغال شد یا در کل منابعی از سیستم گرفته شد چک کنیم که این کار صورت گرفته یا نه در غیر این صورت پیغام خطا صادر کنیم
در مورد اینکه سازنده move یا سازنده copy انتخاب میشه چون چیزی که توسط getContent بر می گرده rvalue هست و rvalue با رفرنس از نوع rvalue یا &&منطبق می شه یعنی سازنده move انتخاب باید بشه. اما به علت بهینه سازی کامپایلرها معمولا نه کپی انجام می شه و نه move که به این کار copy elision گفته می شه. تنها یک متغیر ساخته میشه و کپی و Move صورت نمی گیره

کامبیز اسدزاده
دوشنبه 22 تیر 1394, 17:50 عصر
Problem signature:
Problem Event Name: APPCRASH
Application Name: QtConsole.exe
Application Version: 0.0.0.0
Application Timestamp: 00000000
Fault Module Name: ntdll.dll
Fault Module Version: 6.3.9600.17668
Fault Module Timestamp: 54c846bb
Exception Code: c0000005
Exception Offset: 00042249
OS Version: 6.3.9600.2.0.0.768.101
Locale ID: 1033
Additional Information 1: 5861
Additional Information 2: 5861822e1919d7c014bbb064c64908b2
Additional Information 3: a10f
Additional Information 4: a10ff7d2bb2516fdc753f9c34fc3b069

Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=280262

If the online privacy statement is not available, please read our privacy statement offline:
C:\Windows\system32\en-US\erofflps.txt



برای حل این مشکل Library های زیر رو باید در کنار فایل exe داشته باشید :

libgcc_s_dw2-1.dll
libstdc++-6.dll
libwinpthread-1.dll

ehsan_faal
دوشنبه 22 تیر 1394, 18:26 عصر
سلام
استفاده از unique_ptr در اینجا درست نیست
از کتابخانه هایی که استفاده می شه لازمه مستندات اون به خوبی مطالعه بشه مثل همین کتابخانه c که در اینجا برای خواندن دیرکتوری استفاده شده.
وقتی opendir کردیم در مقابل تابع closedir وجود داره ممکنه opendir فضایی از حافظه را رزرو کنه اما کارهای دیگه هم ممکنه بکنه که فقط با closedir ین کار خاتمه پیدا می کنه نه اینکه اتوماتیک حافظه رزرو شده را با unique_ptr باز پس بدیم
همچنین توی مستندات گفته حافظه ای که توسط readdir رزور می شه را هیچ وقت نباید free کرد چون خود کتابخانه c فکر این کار را هم کرده. اما دوباره با unique_ptr این کار انجام می شه
حالا یه چند نکته در مورد باز کردن فایلها که لازمه وقتی فایلی باز شد یا مثلا حافظه ای اشغال شد یا در کل منابعی از سیستم گرفته شد چک کنیم که این کار صورت گرفته یا نه در غیر این صورت پیغام خطا صادر کنیم
در مورد اینکه سازنده move یا سازنده copy انتخاب میشه چون چیزی که توسط getContent بر می گرده rvalue هست و rvalue با رفرنس از نوع rvalue یا &&منطبق می شه یعنی سازنده move انتخاب باید بشه. اما به علت بهینه سازی کامپایلرها معمولا نه کپی انجام می شه و نه move که به این کار copy elision گفته می شه. تنها یک متغیر ساخته میشه و کپی و Move صورت نمی گیره

منظورتون از این که میگین نه move و نه copy اتفاق نمیفتن رو میشه واضح تر بگین؟
RVO یعنی چیزی که قراره return بشه به جای کپی شدن از متغیر local داخل تابع move بشه داخل تابع caller.
به عنوان آخرین سوال :
مرجعتون واسه این مستندات کجاست؟
راستش من واسه documentation های این لایبرری سرچ کردم چیزی گیرم نیومد.
منبع آفلاین واسه این چیزا هست؟(به جز MSDN البته)
با تشکر

ehsan_faal
دوشنبه 22 تیر 1394, 18:27 عصر
برای حل این مشکل Library های زیر رو باید در کنار فایل exe داشته باشید :

libgcc_s_dw2-1.dll
libstdC++‎-6.dll
libwinpthread-1.dll
امکانش هست به خاطر administrator privilage باشه این اررور؟
چون آدرس یه درایو دیگه رو که میدم درست کار میکنه!

rahnema1
دوشنبه 22 تیر 1394, 18:56 عصر
منظورتون از این که میگین نه move و نه copy اتفاق نمیفتن رو میشه واضح تر بگین؟
RVO یعنی چیزی که قراره return بشه به جای کپی شدن از متغیر local داخل تابع move بشه داخل تابع caller.
به عنوان آخرین سوال :
مرجعتون واسه این مستندات کجاست؟
راستش من واسه documentation های این لایبرری سرچ کردم چیزی گیرم نیومد.
منبع آفلاین واسه این چیزا هست؟(به جز MSDN البته)
با تشکر

در استاندارد در بخش 12.8 و در بند 32 این مطلب را ذکر کرده
همچنین در بخش 12.2 مثالی که زده به همین نکته اشاره کرده
در این مثال به خاطر copy elision ممکنه نتایج getContent مستقیما در فضای مربوط به Content ساخته بشه و move انجام نشه
مستندات مربوط به dirent.h در لینک زیر هست
http://pubs.opengroup.org/onlinepubs/7908799/xsh/dirent.h.html

کامبیز اسدزاده
دوشنبه 22 تیر 1394, 20:04 عصر
امکانش هست به خاطر administrator privilage باشه این اررور؟
چون آدرس یه درایو دیگه رو که میدم درست کار میکنه!

احتمالش هست.
ولی به علت اینکه فایل های کتابخانه dll ها در خود win32 موجود هستند معمولا با مشکل مواجه نمیشه مگر اینکه ویندوز تازه نصب شده باشه و خالی از هر گونه برنامه و پیش نیازات C++ باشه در این حالت بهترین گزینه اینه که فایل های مورد نیاز در کنار برنامه هنگام نصب اضافه شوند.