برنامه نویسی

چرا اندازه این دو ساختار C++ متفاوت است؟

Summarize this content to 400 words in Persian Lang اگرچه برخی از جزئیات ناشناخته C++ ممکن است بر اجرای صحیح برنامه شما تأثیری نداشته باشد، ممکن است بر حافظه مصرف شده توسط برنامه شما تأثیر بگذارد. به عنوان مثال، برنامه زیر دو ساختار تقریباً یکسان را تعریف می کند، با این تفاوت که ترتیب اعضا متفاوت است، اما اگر اندازه دو ساختار را نمایش دهید، متوجه می شوید که data2 4 بایت بیشتر از data1 مصرف می کند.

#include <iostream>
using namespace std;

struct data1 {
char c1;
char c2;
int i1;
int i2;
};

struct data2 {
char c1;
int i1;
char c2;
int i2;
};

int main() {
cout << “sizeof(data1) = ” << sizeof(data1) << “\n”;
cout << “sizeof(data2) = ” << sizeof(data2) << “\n”;
return 0;
}

نتایج اجرای واقعی به شرح زیر است:

sizeof(data1) = 12
sizeof(data2) = 16

برای درک دلیل، باید انواع مختلف تراز آدرس در C++ را درک کنید.

هم ترازی آدرس

در C++، برای دسترسی موثر به حافظه، اشیاء از انواع مختلف باید در آدرس هایی قرار گیرند که مضرب مقادیر خاص هستندتراز آدرس.می توانید بگذرید alignof اپراتور مقدار هم ترازی موقعیت نوع مشخص شده شی را به دست می آورد:

#include <iostream>
using namespace std;

int main()
{
cout << “alignof(int): ” << alignof(int) << endl; // 4
cout << “alignof(double): ” << alignof(double) << endl; // 8
cout << “alignof(char): ” << alignof(char) << endl; // 1
cout << “alignof(float): ” << alignof(float) << endl; // 4
return 0;
}

خروجی به صورت زیر است:

alignof(int): 4
alignof(double): 8
alignof(char): 1
alignof(float): 4

توسط int برای مثال، اگر آدرس‌های حافظه موجود از 1017 شروع می‌شوند، می‌خواهید a را پیکربندی کنید int متغیر، به دلیل اینکه مقدار تراز آدرس آن 4 است، باید به مضرب 4 پیکربندی شود، یعنی از آدرس 1020 شروع شود.از سوی دیگر char، مقدار تراز آدرس آن 1 است، بنابراین اگر می خواهید پیکربندی کنید char متغیرها را می توان مستقیماً از 1017 بدون جابجایی پیکربندی کرد.

بالشتک در تراز آدرس

چیزی که من همین الان دیدم int به عنوان مثال متغیر، 3 بایت را بین 1017 و 1019 هدر می دهد، که به ناملایه گذاریبه همین دلیل است که در ابتدای مقاله دو ساختار با اعضای یکسان اما ترتیب متفاوت اندازه های متفاوتی دارند.

توسط data1 مثلا:

struct data1 {
char c1;
char c2; // 這裡需要補空 2 個位元組
int i1;
int i2;
};

زیرا char مقدار تراز آدرس 1 است، بنابراین دو مورد اول char اعضا را می توان در مجاورت یکدیگر پیکربندی کرد، اما int مقدار تراز آدرس 1 است، بنابراین بین این دو char پس از اینکه عضو باید با 2 بایت پر شود، 4 بایت به اضافه دو بایت آخر را اشغال می کند. int هر کدام 4 بایت را اشغال می کند، بنابراین در مجموع 12 بایت اشغال می شود.

زیر است data2:

struct data2 {
char c1; // 這裡需要補空 3 個位元組
int i1;
char c2; // 這裡需要補空 3 個位元組
int i2;
};

زیرا char و int اعضا به صورت مبهم هستند، بنابراین هر کدام char قبل از اینکه عضو شود باید با 3 بایت پر شود int آدرس‌های اعضا به مضرب 4 تراز می‌شوند که در نتیجه دو می‌شود char اعضا هر کدام 4 بایت به اضافه دو بایت را اشغال می کنند int اعضا، بنابراین در مجموع 16 بایت اشغال شده است.

هنگامی که این تفاوت را درک کردید، می توانید ترتیب اعضا را تنظیم کنید و در صورت لزوم مصرف حافظه را کاهش دهید.

اگرچه برخی از جزئیات ناشناخته C++ ممکن است بر اجرای صحیح برنامه شما تأثیری نداشته باشد، ممکن است بر حافظه مصرف شده توسط برنامه شما تأثیر بگذارد. به عنوان مثال، برنامه زیر دو ساختار تقریباً یکسان را تعریف می کند، با این تفاوت که ترتیب اعضا متفاوت است، اما اگر اندازه دو ساختار را نمایش دهید، متوجه می شوید که data2 4 بایت بیشتر از data1 مصرف می کند.

#include <iostream>
using namespace std;

struct data1 {
    char c1;
    char c2;
    int i1;
    int i2; 
};

struct data2 {
    char c1;
    int i1;
    char c2;
    int i2; 
};

int main() {
    cout << "sizeof(data1) = " << sizeof(data1) << "\n";
    cout << "sizeof(data2) = " << sizeof(data2) << "\n";
    return 0;
}

نتایج اجرای واقعی به شرح زیر است:

sizeof(data1) = 12
sizeof(data2) = 16

برای درک دلیل، باید انواع مختلف تراز آدرس در C++ را درک کنید.

هم ترازی آدرس

در C++، برای دسترسی موثر به حافظه، اشیاء از انواع مختلف باید در آدرس هایی قرار گیرند که مضرب مقادیر خاص هستندتراز آدرس.می توانید بگذرید alignof اپراتور مقدار هم ترازی موقعیت نوع مشخص شده شی را به دست می آورد:

#include <iostream>
using namespace std;

int main()
{
    cout << "alignof(int): " << alignof(int) << endl; // 4
    cout << "alignof(double): " << alignof(double) << endl; // 8
    cout << "alignof(char): " << alignof(char) << endl; // 1
    cout << "alignof(float): " << alignof(float) << endl; // 4
    return 0;
}

خروجی به صورت زیر است:

alignof(int): 4
alignof(double): 8
alignof(char): 1
alignof(float): 4

توسط int برای مثال، اگر آدرس‌های حافظه موجود از 1017 شروع می‌شوند، می‌خواهید a را پیکربندی کنید int متغیر، به دلیل اینکه مقدار تراز آدرس آن 4 است، باید به مضرب 4 پیکربندی شود، یعنی از آدرس 1020 شروع شود.از سوی دیگر char، مقدار تراز آدرس آن 1 است، بنابراین اگر می خواهید پیکربندی کنید char متغیرها را می توان مستقیماً از 1017 بدون جابجایی پیکربندی کرد.

بالشتک در تراز آدرس

چیزی که من همین الان دیدم int به عنوان مثال متغیر، 3 بایت را بین 1017 و 1019 هدر می دهد، که به ناملایه گذاریبه همین دلیل است که در ابتدای مقاله دو ساختار با اعضای یکسان اما ترتیب متفاوت اندازه های متفاوتی دارند.

توسط data1 مثلا:

struct data1 {
    char c1;
    char c2; // 這裡需要補空 2 個位元組
    int i1;
    int i2; 
};

زیرا char مقدار تراز آدرس 1 است، بنابراین دو مورد اول char اعضا را می توان در مجاورت یکدیگر پیکربندی کرد، اما int مقدار تراز آدرس 1 است، بنابراین بین این دو char پس از اینکه عضو باید با 2 بایت پر شود، 4 بایت به اضافه دو بایت آخر را اشغال می کند. int هر کدام 4 بایت را اشغال می کند، بنابراین در مجموع 12 بایت اشغال می شود.

زیر است data2

struct data2 {
    char c1; // 這裡需要補空 3 個位元組
    int i1;
    char c2; // 這裡需要補空 3 個位元組
    int i2; 
};

زیرا char و int اعضا به صورت مبهم هستند، بنابراین هر کدام char قبل از اینکه عضو شود باید با 3 بایت پر شود int آدرس‌های اعضا به مضرب 4 تراز می‌شوند که در نتیجه دو می‌شود char اعضا هر کدام 4 بایت به اضافه دو بایت را اشغال می کنند int اعضا، بنابراین در مجموع 16 بایت اشغال شده است.

هنگامی که این تفاوت را درک کردید، می توانید ترتیب اعضا را تنظیم کنید و در صورت لزوم مصرف حافظه را کاهش دهید.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا