Programming with Microsoft Visual C++.NET 6ed [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming with Microsoft Visual C++.NET 6ed [Electronic resources] - نسخه متنی

George Shepherd, David Kruglinski

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید








Optimizing Storage for Constant Data


Remember that the code in your program is backed not by the swap file but directly by its EXE and DLL files. If several instances of your program are running, the same EXE and DLL files will be mapped to each process's virtual address space. What about constant data? You would want that data to be part of the program rather than have it copied to another block of address space that's backed by the swap file.

You've got to work a little bit to ensure that constant data gets stored with the program. First, consider string constants, which often permeate your programs. You'd think that these would be read-only data, but guess again. Because you're allowed to write code like this (The compiler will compile this code, but you'll get a memory access error if you try to run it.)

char* pch = "test";
*pch = 'x';

The string "test" can't possibly be constant data, and it isn't. If you want "test" to be a constant, you must declare it as an initialized const static or a global variable. Here's the global definition:

const char g_pch[] = "test";

Now g_pch is stored with the code, but where, specifically? To answer that, you must understand the "data sections" that the Visual C++ linker generates. If you set the link options to generate a map file, you'll see a long list of the sections (memory blocks) in your program. Individual sections can be designated for code or data, and they can be read-only or read/write. Table 10-1 lists the important sections and describes their characteristics.
























Table 10-1: Important Sections of a Program


Name


Type


Access


Contents


.text


Code


Read-only


Program code


.rdata


Data


Read-only


Constant initialized data


.data


Data


Read/write


Nonconstant initialized data


.bss


Data


Read/write


Nonconstant uninitialized data


The .rdata section is part of the EXE file, and that's where the linker puts the g_pch variable. The more stuff you put in the .rdata section, the better. The use of the const modifier does the trick.

You can put built-in types and even structures in the .rdata section, but you can't put C++ objects there if they have constructors. If you write a statement such as this one

const CRect g_rect(0, 0, 100, 100);

the linker puts the object into the .bss section, and it will be backed separately to the swap file for each process. If you think about it, this makes sense because the compiler must invoke the constructor function after the program is loaded.

Now suppose you wanted to do the worst possible thing: declare a CString global variable (or static class data member) like this:

const CString g_str("this is the worst thing I can do");

Now you've got the CString object (which is quite small) in the .bss section, and you've also got a character array in the .data section, neither of which can be backed by the EXE file. To make matters worse, when the program starts, the CString class must allocate heap memory for a copy of the characters. You'd be much better off using a const character array instead of a CString object.


/ 319