Is this macro a good way to avoid an AllocSysString() memory leak? - bstr

People in my team (or formerly in my team) did not pay enough attention to memory management of strings in COM. There are far too many example of this:
CString myString = _T("My String");
UseMyStringAsBSTR(myString.AllocSysString());
There is no corresponding call to SysFreeString().
One web page I found suggests a construct like this:
CString myString = _T("My String");
CComBSTR myBstr;
myBstr.Attach(myString);
UseMyStringAsBstr(myBstr);
That will free the allocated memory automatically when myBstr goes out of scope.
It seems to me that this could be simplified by a macro. The following seems to work:
#define MAKE_COMBSTR(bstrName, contents) \
CComBSTR bstrName; \
{ \
CString baseString = (contents); \
bstrName.Attach(baseString.AllocSysString()); \
}
This seems to work, but I'm a little nervous about declaring baseString, calling Attach(), and then having baseString go out of scope. Is there any danger of bstrName trying to baseString's memory after it doesn't exist any more?

Related

With Qt, how to check if stdin is empty?

I have a Qt program that processes stdin data like this:
QTextStream qtin(stdin);
QString stdindata = qtin.readAll();
QByteArray ba;
ba = stdindata.toUtf8();
QJsonDocument exJSONDoc(QJsonDocument::fromJson(ba));
QJsonObject extRoot;
extRoot = exJSONDoc.object();
QStringList keys;
keys = extRoot.keys();
for (int n=0; n <= keys.count()-1; n++)
{
qDebug() << extRoot.value(keys[n]).toString();
}
It works when I call my program like this:
myprogram < ./data.json
But if I call it without any "<" it hangs in qtin.readAll().
How can I check with Qt if the stdin is empty?
(I am assuming a Linux -or at least POSIX- operating system)
QTextStream qtin(stdin);
QString stdindata = qtin.readAll();
This would read stdin till end-of-file is reached. So works with a redirected input like
myprogram < ./data.json
But if I call it without any "<" it hangs ...
But then (that is, if you run myprogram alone) stdin is not empty. It is the same as your shell's stdin. and your program, being the foreground job, is waiting for input on the terminal you are typing (see also tty(4)). Try (in that case) typing some input on the terminal (which you could end with Ctrl D to make an end-of-file condition). Read about job control and the tty demystified and see also termios(3).
Perhaps you could detect that situation with e.g. isatty(3) on STDIN_FILENO. But that won't detect a pipe(7) like
tail -55 somefile | myprogram
You need to define what an empty stdin is for you. I have no idea what that means to you, and I would instead think of myprogram < /dev/null (see null(4)) as the way to get an empty stdin.
Perhaps you should design myprogram so that some program
option (perhaps --ignore-stdin) is avoiding any read from stdin.
Problem here is readAll. See documentation:
Reads the entire content of the stream, and returns it as a QString.
Avoid this function when working on large files, as it will consume a
significant amount of memory.
So it reads stdin until it encounters end of file and since stdin is associated with console you have to signal end of file. Usually it is Ctrl-D and press enter.
It is more probable you what to read stdin line by line.
To alow user text editing console transfers data to standard input of the application only line by line. This was designed like this ages ago when computer had only a printer as user interface (no screen).
Now question is how to read JSon form stdin console connected with console without end of file information?
I would use some SAX parser, but this would be to complicated for you.
So is there another way to detect end of JSon?
You can try this approach (this is basic idea, not final solution, so it has couple shortcomings):
QFile file(stdin);
QByteArray data = file.peak(largeNumber);
QJsonParseError error;
QJSonDocument doc = QJSonDocument::fromJson(data, &error);
while (!doc.isValid() && JSonNotTerminatedError(error.error))
{
// TODO: wait for new data - it would be best to use readyRead signal
doc = QJSonDocument::fromJson(data, &error);
}
Where JSonNotTerminatedError returns true for respective QJsonParseError::ParseError values (see linked documentation) which are related with unterminated JSon data.
Now I see QFile doesn't have required constructor, but main concept should be clear. Read data from stdin and check if it is a valid JSon document.

XC8 builds font tables from top ROM

I wrote a barebone progran template in XC8 (1.37) that I use to develop and test new GLCD functions for the 18F family. Programming is done via a PICkit3. Since I need to quicky reprogram several times the code it is really important that programming is faster as much as possible.
Tipically, the code size is around 2K and it takes less than 10 sec to program,
Everiything is fine until I must use a font table, defined as:
const char font8[] = {....
Now, with just $400 bytes added, the compiler place the table at the ROM's end and the programming of 64K memory takes more than 1 minute.
Is there any way to avoid this?
I tried to manually limit the memory range in the MPLABX options, but this is annoying and a little unsafe (sometimes part of code is truncated).
A while back I had to write some code for emissions testing, where I needed to copy data between extreme ends of RAM. To do that I needed to specify the exact memory addresses. You can also use the C extension __at() construct. http://ww1.microchip.com/downloads/en/DeviceDoc/50002053F.pdf#page=27
int scanMode __at(0x200);
const char keys[] __at(123) = { ’r’, ’s’, ’u’, ’d’};
int modify(int x) __at(0x1000) {
return x * 2 + 3;
}

Iterating through !DumpHeap output to read value at memory offset

I'm trying to come up with a WinDbg command line expression that takes the output of the !DumpHeap command and for each address, reads a 64-bit value from offset 0x08 after the address. I think this is possible (not sure about it) but every attempt I made so far fails with some error.
I searched a lot but most WinDbg articles show simple examples which I can try but my attempts fail.
I have a process dump of an ASP.NET worker process. The process has some memory growth but there's no clear offender so I'm trying to list a number of objects that appear many times in memory. I'm using sos.dll for the managed debugging WinDbg extensions.
Here's what I'm trying to do
.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{r #$t0=poi(myaddress+0x8);!do #$t0;.echo ************* myaddress}
Note, that the above command must be on a single line - I only added a line break for better readability here.
For the above line, WinDbg prints this error: Couldn't resolve error at 'myaddress+0x8);!do #$t0;.echo ************* 00000001003cb870'.
I'm trying to iterate through all addresses returned by !DumpHeap - each address should go into the myaddress variable. Then, for each address, I'm trying to set the $t0 user register to the value read from myaddress+0x8. The !do (!DumpObject) command would then dump the object at that address.
If I run only (again, on one line in WinDbg):
.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{!do myaddress;.echo ************* myaddress}
I get a list of object dumps but this is one level higher than what I need. I want to drill down one level deeper and dump a particular member of these top-level objects that I'm iterating through.
Is this possible or am I on the wrong track with this?
After further searching, I found that I was using the wrong syntax. According to question and to MSDN, variable names must be surrounded by spaces or must be enclosed in ${...} to work. After I used the ${} enclosure, my script started working.
For future reference, here's how to run the script (keep it on one line in WinDbg):
.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{r #$t0=poi(${myaddress}+0x8);!do #$t0;.echo ************* myaddress}
yes you need space around the aliases
.foreach ( place { .shell -ci "!DumpHeap -stat" sed 1,3d | awk "{print
$1 }" } ) { .foreach (plays { !DumpHeap -short -mt place } ) { r $t0 =
poi( plays + 8 ) ; !do #$t0 ; .echo
========================================= } }

how to get Disk Space used/free/total in Common Lisp

Seems that there is no standard functions to get used/free/total of Disk space in Common Lisp.
There is statvfs.h in Linux/Mac and GetDiskFreeSpaceEx function in Windows for C/C++.
Personally, it would call an executable to do that using a library.
Calling df -h with IOLib for example.
But this is not portable (particularly IOLib, but there are other libraries), and you have to parse the output of the commands.
That's one reason I love programs which have "machine readable" outputs: you can glue them up programmatically (à la shell script).
Another way would be to actually call these c function, using cffi or uffi (ffi standing for foreign function interface), but I haven't used neither, so I can't say much about it.
Oh, search on quickdocs.org, there is probably a library exactly for that, or maybe just to access the OS's API.
I wrote a new project cl-diskspace using statvfs to get disk total/free/available space in Common Lisp. Support Mac/Linux/Windows.
Update: 2015-07-11 now support Windows! Thanks to pjb, Guthur, Fare, |3b|
Install cl-diskspace with QuickLisp:
$ git clone https://github.com/muyinliu/cl-diskspace.git
$ cp -r cl-diskspace ~/quicklisp/local-projects/
Load cl-diskspace with QuickLisp:
(ql:quickload 'cl-diskspace)
Usage of cl-diskspace:
Get disk space information
(diskspace:disk-space "/")
Will get something like this:
127175917568
16509661184
16247517184
Means that the total space is 118.44G, free space is 15.38G and available space is 15.13G
Get disk total space
(diskspace:disk-total-space "/")
Will get something like this:
127175917568
Get disk free space
(diskspace:disk-free-space "/")
Will get something like this:
16509661184
Get disk available space
(diskspace:disk-available-space "/")
Will get something like this:
16247517184

Building argv and argc

I'm a student programmer using Qt to build a GUI application for work. The primary purpose of this application is to open some of our old style files, allows better editing and then save the file in a new format and file extension. Recently I have been asked to allow this conversion to take place from a terminal. While I do know what argv and argc are along with what they represent I am unsure how to accomplish what they want. For instance how to handle relative paths vs. absolute... maybe how to get absolute from relative; perhaps none of that is even needed. My programming experience has been primarily with guis so this is a little new to me.
Users would like the following to be ran from the terminal
application -o /fileLocation /fileDestination template(to determine new format)
I began to use for loops and if statements to begin accomplishing this when I relized that I might be taking the worng approach to all of this. I WOULD ALSO BE REALLY INTERESTED IF QT HAS SOMETHING FOR THIS! Here is what I have began coming up with:
int main(int argc, char *argv[])
{
if(argc > 1)
{
for(int i = 0; i < argc; i++)
{
if(argv[i] == "-c")
{
QString fileName = QString::fromStdString(argv[i+1]);
QString fileDestination = QString::fromStdString(argv[i+2]);
QString templateName = QString::fromStdString(argv[i+3]);
QFile fileToConvert(fileName);
if(fileToConvert.open(QFile::ReadOnly))
{
//do stuff
Thanks for reading my post and a big thanks for any contributions you make to helping me overcome this issue.
if(argv[i] == "-c")
You can't compare C strings like that. You can compare characters, so you could do
if(argv[i][0] == '-' && argv[i][1] == 'c')
But in Qt you should be using the QApplication::arguments see Obtaining command line arguments in a Qt application

Resources