Tuesday, October 19, 2010
Executing Wild Cards from C programs
or
we will use execl(...) to do that.
First we will understand the difference excel(..) and system(...) calls:
1) execl(...) it executes as it is by doing fork.. so wild cards will not be effected.
but system(...) call spawns shell and does fork and and execute the command provided as arguments.
2) System(...) is blocking call. It blocks the flow of execution. Where as execl(...) is not that it just spawns a fork and the parent process will not get blocked.
we can't use wildcards using execl(...) reason is execl() will not spawn any shell where in wildcards can be understood. so if we would like to use wildcards then how we should write is
execl("/bin/bash" ,"bash", "-c", "rm -f /home/cc/rr* ", (char*)0);
send the parameters as arguments to bash. then it works..
Same can be executed as
bash$ bash -p rm -f /home/cc/rr*
Wednesday, February 24, 2010
multi-statement macros - A Coding practise
I have a macro
#define SWAP(X,Y) { X = X+ Y; Y = X - Y; X = X - Y; }
So, The above macro swaps two numbers.
I can use
int x = 5, y =4;
SWAP(x,y);
Works perfect.
Now I will use the same as
if ( x > 0)
SWAP(X,Y);
The above one also works fine.
Now
if ( x > 0)
SWAP (x,y);
else
printf("\n X is Below Zero");
So..will the above works.
Noooo..
Before getting solution let us understand the problem my expanding:
if (x > 0)
{
x =x + y;
y = x - y;
x = x -y;
};
else
printf("\n X is Below Zero");
If we compile the above we will get the error like "
"ERROR!!! "parse error before else"
Because of the extra semi-colon before Else.
So, the solution is embed the multi-staement macro between do-while(0) loop :)
So, the macro defination would be
#define SWAP(X,Y) \
do { \
X = X+ Y; \
Y = X - Y; \
X = X - Y; \
}while (0)
Thats it..
This is the safest way of using multi-statemetn macros ..
OR
There is another Simple way which is bruit-forcing a coding standard for coders ...and here is the rule:
Never forget to use parenthesis even the functional block has one statement
that means
instead of using
if (x > 0)
SWAP (x,y);
else
printf("\n X is Below Zero");
we should use :
if (x > 0)
{
SWAP(x,y);
}
else
{
printf("\n X is Below Zero");
}
Sunday, February 21, 2010
Boost Pointers
scoped_ptr
for automatic destruction:Using normal pointers | Using scoped_ptr |
Collapse void Sample1_Plain() { CSample * pSample(new CSample); if (!pSample->Query() ) // just some function... { delete pSample; return; } pSample->Use(); delete pSample; } | Collapse #include "boost/smart_ptr.h" void Sample1_ScopedPtr() { boost::scoped_ptr<CSample> samplePtr(new CSample); if (!samplePtr->Query() ) // just some function... return; samplePtr->Use(); } |
The boost::shared_ptr
implementation has some important features that make it stand out from other implementations:
shared_ptr<T>
works with an incomplete type:When declaring or using a
shared_ptr<T>
,T
may be an "incomplete type". E.g., you do only a forward declaration usingclass T;
. But do not yet define howT
really looks like. Only where you dereference the pointer, the compiler needs to know "everything".shared_ptr<T>
works with any type:There are virtually no requirements towards
T
(such as deriving from a base class).shared_ptr<T>
supports a custom deleterSo you can store objects that need a different cleanup than
delete p
. For more information, see the boost documentation.- Implicit conversion:
If a type
U *
can be implicitly converted toT *
(e.g., becauseT
is base class ofU
), ashared_ptr<U>
can also be converted toshared_ptr<T>
implicitly. shared_ptr
is thread safe(This is a design choice rather than an advantage, however, it is a necessity in multithreaded programs, and the overhead is low.)
Using shared_ptr in containers
Many container classes, including the STL containers, require copy operations (e.g., when inserting an existing element into a list, vector, or container). However, when this copy operations are expensive (or are even unavailable), the typical solution is to use a container of pointers:
Collapsestd::vector<CMyLargeClass *> vec; vec.push_back( new CMyLargeClass("bigString") );
However, this throws the task of memory management back to the caller. We can, however, use a
shared_ptr
:Collapsetypedef boost::shared_ptr<CMyLargeClass> CMyLargeClassPtr; std::vector<CMyLargeClassPtr> vec; vec.push_back( CMyLargeClassPtr(new CMyLargeClass("bigString")) );
Very similar, but now, the elements get destroyed automatically when the vector is destroyed - unless, of course, there's another smart pointer still holding a reference.
Rules : shared_ptr usage
- When creating a smart pointer, you explicitly have to write
..._ptr<T> myPtr(new T)
- You cannot assign a
T *
to a smart pointer - You cannot even write
ptr=NULL
. Useptr.reset()
for that. - To retrieve the raw pointer, use
ptr.get()
. Of course, you must not delete this pointer, or use it after the smart pointer it comes from is destroyed, reset or reassigned. Useget()
only when you have to pass the pointer to a function that expects a raw pointer. - You cannot pass a
T *
to a function that expects a_ptr<T>
directly. You have to construct a smart pointer explicitly, which also makes it clear that you transfer ownership of the raw pointer to the smart pointer. (See also Rule 3.) - There is no generic way to find the smart pointer that "holds" a given raw pointer. However, the boost: smart pointer programming techniques illustrate solutions for many common cases.
- No circular references - If you have two objects referencing each other through a reference counting pointer, they are never deleted. boost provides
weak_ptr
to break such cycles (see below).
- When creating a smart pointer, you explicitly have to write
Saturday, February 13, 2010
find and replace in a set of files using VIM
Thursday, February 11, 2010
A Coding Practise for Structure Assignment
This is in general can be a part of coding guidelines if we dont have.
NEVER USING = OPERATOR TO ASSIGN THE STRUCTURES. WE SHOULD RECOMMEND TO USE MEMCPY INSTEAD.
ex:
struct {
int rollNum;
name char[255];
} s1, s2;
Here lets suppose if we want to copy the data from s2 to s1 variable.
we can allways do
s1 = s2;
which is correct also.
But let us take an hypothetical scenario wherein we want to make this student structure into a member variable for another structure like
struct ScoreCard {
struct student s;
};
struct ScoreCard *pScoreCard;
pScoreCard = (struct ScoreCard *)malloc(sizeof(struct ScoreCard));
then (s1 = s2 ) kind of code breaks if we do as
pScoreCard->s = s2;
reason being pScoreCard is heap memory and it leads to SEGV.
Let us suppose coder wrote as (as per the new guideline)
memcpy(&s1, sizeof(struct student), &s2);
then there is mere change the the above one by prefixing the pointer
memcpy(pScoreCard->s1, sizeof(struct student), &s2).
Thats it.