开发者

GetPrivateProfileString - c++ class - return string - memory pre calculation

In GetPrivateProfileString, lpReturnedString returns the string value present in the key of a particular section of an ini file.

My question is tha开发者_C百科t how will i know exactly, how much memory has to be allocated, rather than just allocation a large chunk prior to calling this function.

DWORD WINAPI GetPrivateProfileString(
  __in   LPCTSTR lpAppName,
  __in   LPCTSTR lpKeyName,
  __in   LPCTSTR lpDefault,
  __out  LPTSTR lpReturnedString,
  __in   DWORD nSize,
  __in   LPCTSTR lpFileName
);


Standard case

The return value from GetPrivateProfileString is the number of characters copied to the buffer, not including the null terminator.

Therefore, you could start with (say) a buffer of 100 _TCHARs and check the return value. If it’s 99, then either you exactly guessed the size of the string or (more likely) your buffer is too small, so enlarge it and try again.

“Enumerating” case

The above applies to the standard case of retrieving one string value from an .ini file. If you are instead passing NULL as either the lpAppName or lpKeyName parameters, in order to enumerate all available values, and you have provided too small of a buffer, the return value will be two less than the buffer size.

Allocation Strategy

You’re going to have to dynamically allocate the buffer. So you’ll probably use std::auto_ptr or std::unique_ptr, or maybe a std::vector<_TCHAR> that you can resize() as needed. If you don’t know in advance how big the strings will be, I’d recommend starting with something like 250 _TCHARs and doubling the size each time you find out the buffer is too small. In practice, I’d bet 250 is enough 99.9999% of the time.

Alternatives

XML file stored under %APPDATA%; JSON file stored under %APPDATA%, the Registry…


That's weird, generally Windows API functions allow you to pass in a NULL and return to you the size to make your buffer. This function doesn't seem to do that. I'd say you should just pick a reasonable size. If it's not big enough, keep doubling the buffer size until you get it.


From your question I suppose that you want allocate memory on the heap with new, malloc, LocalAlloc or some other function working with heap. You want probably use as less heap memory as possible.

If you works with the memory on the stack it is not so important to be so exactly. Memory allocation is very quickly (about 100 or 1000 time quicker as on the heap) and after you return from the current function the memory will be automatically freed. So you can just define a variable

TCHAR szBuffer[16384];

16K on the stack is almost nothing. Then you can call GetPrivateProfileString with szBuffer as the lpReturnedString. The function GetPrivateProfileString returns the number of characters copied to the buffer. If the value is less then 16K-1, then you will be know the the exact buffer size. You can allocate now the memory block of the size on the heap and copy the data from szBuffer to the block. If the returned value of GetPrivateProfileString is equal to 16K-1, then you the buffer was too small. In the case you can implement any doubling of the buffer size (and working with buffer of the heap now), but I prefer to interpret this as an error in the ini-file. All real ini-files which I used before was small. The size of an entry is mostly less then 260 characters. So the entry size grater as 16K you can interpret as the error.

By the way you can verify the size of the INI-file with respect of GetFileSizeEx. The entry size must be less then the size of the INI-File.

Some restriction to the INI-size you have to include in your program. If the entry size will be measured in GBs, that you can do receive a problem. Why not restrict the size of permitted entry with 16K for example?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜