Tuesday, March 24, 2009

Careful when using strncpy

Copy characters from string

Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.

No null-character is implicitly appended to the end of destination, so destination will only be null-terminated if the length of the C string in source is less than num.

Parameters

destination
Pointer to the destination array where the content is to be copied.
source
C string to be copied.
num
Maximum number of characters to be copied from source.

Return Value

destination is returned.


Friday, January 16, 2009

string in hex

Sometimes, I need to see characters of a string in Hex values:

void printhex(unsigned char* str)
{
    for (int j=0;j<strlen(str);j++)
        printf("%02X ", str[j] );
}

Thanks to mibrahim (encdec).



pointer to const memory

char * s = "ab";
memset(s, 0 , strlen(s)); //empy string

This code won't run because s is considered pointer to const char.
As well, this applies on a statement like this:

memcpy(s, "\0\0" , strlen(s));

That's because the compiler first reserved a memory space to hold the value "ab" then it returns to you a pointer to it. i.e. this is not considered intialization of the pointer.
Of course, defining s as an array of characters will be ok, where s will be handled as a normal variable that can be inialized not as pointer to const memory.

strlen() vs. sizeof() Tip

Only use sizeof() for locally allocated buffers.
Always use strlen() for variables passed from outside.

Why: using sizeof() with a pointer to char passed to you will return
the size of the pointer itself (which is 4 always) not the size of the
allocated space to that buffer.

Why Dynamic Allocation is slower and may fail?

Usually, memory is allocated from a large pool of unused memory area called the heap (also called the free store). Since the precise location of the allocation is not known in advance, the memory is accessed indirectly, usually via a reference. The precise algorithm used to organize the memory area and allocate and deallocate chunks is hidden behind an abstract interface and may use any of the methods described below.

Problems during fullfiling allocation request include Internal and external fragmentation.
Memory Fragmentation

From Wikipedia



Static vs. Dynamic vs. Automatic Variable

Static memory allocation refers to the process of allocating memory at compile-time before the associated program is executed, unlike dynamic memory allocation or automatic memory allocation where memory is allocated as required at run-time.

An application of this technique involves a program module (e.g. function or subroutine) declaring static data locally, such that these data are inaccessible in other modules unless references to it are passed as parameters or returned. A single copy of static data is retained and accessible through many calls to the function in which it is declared. Static memory allocation therefore has the advantage of modularising data within a program design in the situation where these data must be retained through the runtime of the program.

The use of static variables within a class in object oriented programming enables a single copy of such data to be shared between all the objects of that class.

Object constants known at compile-time, like string literals, are usually allocated statically. In object-oriented programming, the virtual method tables of classes are usually allocated statically.

From Wikipedia

Tuesday, November 25, 2008

C/C++ Pointer Arithmetic notes

when you say:
int *p = ...
p++; /* means p = p + sizeof(int) */

what about void pointers?
void *p = ...
p++; /* compiler error */

as the size of void is unknown.

also,

(int*)pvoid++; // will not compile because the increment operator has higher Precedence than casting
i.e: the casting is for the increment result. so, you are still incrementing a void pointer.

to increment a void pointer you can use

pv = (void*)(((int*) pv)+1);
to increment the void pointer as integer pointer. but, the increment will be with the sizeof(int)

example:
int x[2] = {5,6};
int *p = x;
void *pv = (void*)p ;

pv = (void*)(((int*) pv)+1);

printf("%d\n",*(int*)pv);

or simply you can define a pointer to integer and increment it.
example:

int *p = (int*) pVoid;
p++;