Archive for the ‘Sm Stuff’ Category

How do you rate yourself in C?

August 27, 2007

This is a tricky question. When I began attending interviews,
my answer used to be a number, say, 5. Actually, the answer
is more than this. If you give a proper explaination and then
arrive on a number, you have impressed the interviewer.
These days, I would answer it in this way:

“I have been learning C since a good time. My learning is
majorly from experimenting small-small programs. I understand
various data types, qualifiers, syntax rules, and program
execution, etc. I also have advanced (or beginner’s) knowledge
of C internals like writing for portability, efficient usage of
C constructs, understanding of pointers, etc. (These details
would change from person to person.) Keeping all these facts
in mind, I can safely rate myself at 6.5.

I am reserving the rest 3.5 for understanding the C grammar,
C99 details and related issues.

Advertisements

how to convert a multibyte char to unsigned long or any type

August 27, 2007

What is bus error? n segmentation fault?

August 27, 2007

the C standard does not define either “bus
error” or “segmentation fault”, these are things that happen with your
particular compiler on your particular operating system.

In general, they are both the result of something wrong in your
program, an error that produces undefined behavior. When your program
generates undefined behavior C no longer specifies what might happen,
and things like “bus error” and “segmentation faults” are the results
of certain types of undefined behavior on your particular system.

To find out for sure you need to ask in a group that supports your
particular compiler/OS combination.

For several common such combinations, a segmentation fault results
when your program tries to access memory that does not belong to it,
for example with an uninitialized or null pointer, or writes past the
end of allocated memory. Bus faults generally result when you play
games with pointer conversions and access a variable using a pointer
with incorrect alignment.

Bus error occurs when hardware tells the OS about a problematic memory
reference. In practice, a bus error is almost always caused by a
misaligned read or write. It’s called a bus error, because the address
bus is the component that chokes if a misaligned load or store is
requested.

Alignment means that data items can only be stored at an address that
is multiple of their size.

A program to cause a bus error is:

union {
char a[10];
int i;
}u;

int *p = (int*) &(u.a[1]);
*p = 17; /* the misaligned addr is p causes a bus error */

A bus error can also be generated by referencing memory that does
not physically exist.

Simply, a bus error means that the CPU disliked something about
that memory reference, while segv means that the MMU disliked
something about it.

//2nd way for answering it..

It’s easier to understand bus errors when you take a look at assembler
programming. Often you have commands to access single bytes, two bytes
a once (often called a word) or 4 bytes (often call long). Thus you
may have e.g. commands to move data from or to a CPU register (or
between memory locations) like

MOVE.B source, dest // moves single byte
MOVE.W source, dest // moves two bytes at once
MOVE.L source, dest // moves four bytes at once

The compiler will of course try to use a single command if possible
since it’s faster than having to move the several bytes individually.
So, if the size of an int on your machine is 4 bytes, it will usually
use the MOVE.L version to move int data .

But on some machines MOVE.L can only be used with memory addresses
that can be divided by 4. If you try use it (or the compiler creates
machine instructions that would do this) you get a bus error. And
it’s often rather simple to get the compiler to do so, if you have
e.g.

char *buf = malloc( 100 );
int a = * ( int * ) ( buf + 13 );

This code is rather likely to result in a bus error on these kinds of
machines. On other architectues (like, for example, INTEL processors)
it only results in slower execution speed. That’s often a problem
with code that doesn’t take this into account, the program seems to
work flawlessly on an INTEL processor but on other architectures (SUN
with Solaris is a typical example, AFAIR) it fails with bus errors.

That’s also why malloc() and friends always have to return properly
aligned memory – since malloc() don’t know what you’re going to use
the memory for it has to return memory starting at an address that
can be accessed with the instructions for the widest type on your
machine.

Also the necessity for padding bytes in structures is a direct result
of these alignment issues. On a machine with 4 byte integers you will
have (at least) three padding bytes betwen the ‘x’ and ‘y’ member in
a structure like

struct {
char x;
int y;
} my_struct;

because otherwise writing ‘my_struct.y’ would result in an unaligned
access, leading to a bus error.

Segmentation faults are something completely different. You get them
when you try to access memory that either does not exist or which you
have no permission to access.

//3rd way for answering it

For a microprocessor (CPU, GPP, etc.) there are pins connecting the chip
to memory. This colletion of pins is called the BUS. There is a data bus
and an address bus. To reduce the number of pins on a chip, some
manufacturers will skip having an A0 pin. This means the last bit in the
address is assumed to always be zero. Or in other words, all addresses
must be even, e.g. 0, 2, 4, 6, 8, 10, etc. Some manufacturers drop pins A0
and A1. Thus addresses need to be a multiple of four, e.g. 0, 4, 8, 12,
16, 20, etc. If I wanted to address memory location 1 the compiler will
actually fetch 2 bytes from memory loction 0 then shift everything so I
only have the data from memory location 1. It does this without you, a C
programmer, ever knowing. So I write:

char array[10];
int i;

for(i = 0; i < sizeof array; i++) {
array[i] = i;
}

but the compiler will optimize it. It will store 0, 1 into memory location
0, it will store 2, 3 in memory location 2, etc. It will physically be
doing:

for(i = 0; i < sizeof array; i += 2) {
/* store the value of array[i] and array[i+1]
* in one pass.
*/
}

The compiler knows to do this ‘trick’ because we are using char. There are
ways of messing up the compiler. Simplest way:

char array[10];
int *p = (int *)1;
*p = 0; /* bus error */
or
p = &array[1]; /* odd address */
*p = 0; /* bus error */

The compiler understands that p is a pointer to int. It therefore assumes
it does not need the special ‘trick’. It assumes p will always hold an
even address. By assigning p an odd address we confuse the compiler and it
creates a bus error. Another more subtle way is:

int i = 1;
scanf(“%d”, i); /* should have been scanf(“%d”, &i); */

we tell scanf we are passing the address of an integer. Instead we pass
the VALUE of the integer. The scanf function will assume 1, the value of
i, is a valid address. A bus error will occur.

NOTE: Only on machines with no A0 pin will a bus error occur.

Some compilers and/or operating systems create blocks of memory they call
segments for a program. The code will go in one segment, auto variables
will go in another segment, maybe local variables will go in a different
segment, dynamically allocated memory will be another segment, etc. The
options as to what constitutes a segment is different from compiler to
compiler. In some cases it might decide some segments are RAM, some are
ROM (Read Only Memory), some are NONE (no read or write). If you try
writing to a ROM you are going to get a segmentation fault. If you try
writing to NONE you are going to get a segmentation fault.

For example, string literals might be in ROM. So this will cause a
segementation fault:

char *s = “string literal”;
s[0] = ‘S’; /* segmentation fault */

The string might exist in ROM. So when I attempt to use s[0] = ‘S’; I am
attempting to WRITE to ROM and I get a segmentation fault. Additionally,
this will segmentation fault:

#include <ctype.h>
#include <stdio.h>

int main(void)
{
char *c = (char *)0;
while(1) {
if(isprint(*c))
putchar(*c);
else
putchar(‘\n’);
c++;
}

return 0;
}

Sooner of later this is going to attempt to read from NONE memory and
segmentation fault. On most machines it will segmentation fault on the
first read because memory location 0 is NONE to all but system tasks.

C program which is used to find the memory

August 27, 2007

It depends on OS u r using

In Linux, you can read /proc/meminfo file to find out the RAM size.

Dos store the size of RAM in a particular memory location

+ In the Symbian OS, the media driver for a givenstorage device provides the functionality to get thesize of the storage.