Monday, June 10, 2019

zero length array in C

 zero length array in C


Ref from here: http://edusagar.com/articles/view/19/zero-length-array-in-C

Declaring Zero length array in place of normal pointers is a common programming practice in networking jargon where we have to implement header of a payload to be passed across network. In this article, we will discuss how we can implement variable length payload using the concept of zero sized array.

* Declaration of zero length array
 struct payload {
         int length;
         char data[0];
 };
    The above declaration creates a structure for a network payload, for which we can define the length of the payload in field "length" and the variable length data would go in field "data".

* How is this different from pointers ?   
struct payload {
        int length;
        char *data;
 };
    The above declaration seems similar to what we had earlier and looks like well suited for the payload data-structure. However, there is a subtle difference when we consider sending data over network. To use this structure as a payload, let us allocate the memory first and see why this is not a good choice for network payloads.

    struct payload *p = (struct payload *)malloc(sizeof(struct payload));
    p->data = (char*)malloc(sizeof(char) * payload_len);
    p->length = payload_len;
    p->data = //assign data.

    Memory allocation will return different memory address from Heap for base address(p) and data(p->data) and thus is not aligned with the base address of the payload structure. To send this structure over network, we have to start from the base address of the given structure and start copying the required number of bytes one by one over the network. But, the base address of the structure is not at the same memory chunk as that of the data. Hence, simple byte by byte copying of the payload to the network is not possible in this case.
    This is where the zero sized array comes into picture. Due to its declaration syntax, the memory address of the field data is properly aligned with the base address of the payload structure (data is at offset of 4 bytes from the base address). This is how we allocate memory for this:

    struct payload *p = (struct payload *)malloc(sizeof(struct payload) + payload_len*sizeof(char));
    p->length = payload_len;
    p->data = //assign data.

    In this case we are allocating the whole memory in one big chunk and also it is easily accessible by adding offset of '4' (considering size of int as 4 bytes) to the base address allocated in above malloc() call. Hence, while sending the data over the network, we can simply send the base address of the packet with properly filling up the length of upcoming data. And at the receiving end we can very easily convert back the data easily from this payload structure.

 Ref: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

Wednesday, June 5, 2019

string operations


1. split the string based on the delimiter

Ref: https://www.codingame.com/playgrounds/14213/how-to-play-with-strings-in-c/string-split

2. reverse a words in a string and not a character:

way1:
https://www.geeksforgeeks.org/print-words-string-reverse-order/

way2:


SELVATHA-M-V0HE:test selvatha$ more string.c
#include <stdio.h>
#include <string.h>

int main()
{
        char str[] = "strtok needs to be called several times to split a string";
        int init_size = strlen(str);
        char delim[] = " ";
        char *array[20];
        int i=0,size;

        char *ptr = strtok(str, delim);
        array[i]=ptr;

        while(ptr != NULL)
        {
                i++;
                printf("'%s'\n", ptr);
                ptr = strtok(NULL, delim);
                array[i]=ptr;
        }
        size=i;

        printf("printing the char array\n");
        /* This loop will show that there are zeroes in the str after tokenizing */
        for (i = 0; i < size; i++)
        {
                printf("'%s'\n", array[i]);
        }
        printf("\n");

        return 0;
}
SELVATHA-M-V0HE:test selvatha$ gcc string.c 
SELVATHA-M-V0HE:test selvatha$ ./a.out
'strtok'
'needs'
'to'
'be'
'called'
'several'
'times'
'to'
'split'
'a'
'string'
printing the char array
'strtok'
'needs'
'to'
'be'
'called'
'several'
'times'
'to'
'split'
'a'
'string'

Ref: https://www.codingame.com/playgrounds/14213/how-to-play-with-strings-in-c/string-split

Monday, June 3, 2019

array and pointer

Array and pointer/array of pointer vs pointer to array:

 Taken from this link for caching: https://www.geeksforgeeks.org/pointer-array-array-pointer/

Pointer to Array
Consider the following program:
filter_none edit
play_arrow
brightness_4
#include<stdio.h>
  
int main()
{
  int arr[5] = { 1, 2, 3, 4, 5 };
  int *ptr = arr;
  
  printf("%p\n", ptr);
  return 0;
}
In this program, we have a pointer ptr that points to the 0th element of the array. Similarly, we can also declare a pointer that can point to whole array instead of only one element of the array. This pointer is useful when talking about multidimensional arrays.
Syntax:
data_type (*var_name)[size_of_array];
Example:


int (*ptr)[10];
Here ptr is pointer that can point to an array of 10 integers. Since subscript have higher precedence than indirection, it is necessary to enclose the indirection operator and pointer name inside parentheses. Here the type of ptr is ‘pointer to an array of 10 integers’.
Note : The pointer that points to the 0th element of array and the pointer that points to the whole array are totally different. The following program shows this:
filter_none edit
play_arrow
brightness_4
// C program to understand difference between 
// pointer to an integer and pointer to an
// array of integers. 
#include<stdio.h>
  
int main()
{
    // Pointer to an integer
    int *p; 
      
    // Pointer to an array of 5 integers
    int (*ptr)[5]; 
    int arr[5];
      
    // Points to 0th element of the arr.
    p = arr;
      
    // Points to the whole array arr.
    ptr = &arr; 
      
    printf("p = %p, ptr = %p\n", p, ptr);
      
    p++; 
    ptr++;
      
    printf("p = %p, ptr = %p\n", p, ptr);
      
    return 0;
}
Output:
p = 0x7fff4f32fd50, ptr = 0x7fff4f32fd50
p = 0x7fff4f32fd54, ptr = 0x7fff4f32fd64
p: is pointer to 0th element of the array arr, while ptr is a pointer that points to the whole array arr.
  • The base type of p is int while base type of ptr is ‘an array of 5 integers’.
  • We know that the pointer arithmetic is performed relative to the base size, so if we write ptr++, then the pointer ptr will be shifted forward by 20 bytes.
The following figure shows the pointer p and ptr. Darker arrow denotes pointer to an array.

On dereferencing a pointer expression we get a value pointed to by that pointer expression. Pointer to an array points to an array, so on dereferencing it, we should get the array, and the name of array denotes the base address. So whenever a pointer to an array is dereferenced, we get the base address of the array to which it points.
filter_none edit
play_arrow
brightness_4
// C program to illustrate sizes of
// pointer of array
#include<stdio.h>
  
int main()
{
    int arr[] = { 3, 5, 6, 7, 9 };
    int *p = arr;
    int (*ptr)[5] = &arr;
      
    printf("p = %p, ptr = %p\n", p, ptr);
    printf("*p = %d, *ptr = %p\n", *p, *ptr);
      
    printf("sizeof(p) = %lu, sizeof(*p) = %lu\n",
                          sizeof(p), sizeof(*p));
    printf("sizeof(ptr) = %lu, sizeof(*ptr) = %lu\n"
                        sizeof(ptr), sizeof(*ptr));
    return 0;
}
Output:
p = 0x7ffde1ee5010, ptr = 0x7ffde1ee5010
*p = 3, *ptr = 0x7ffde1ee5010
sizeof(p) = 8, sizeof(*p) = 4
sizeof(ptr) = 8, sizeof(*ptr) = 20
Pointer to Multidimensional Arrays

  1. Pointers and two dimensional Arrays: In a two dimensional array, we can access each element by using two subscripts, where first subscript represents the row number and second subscript represents the column number. The elements of 2-D array can be accessed with the help of pointer notation also. Suppose arr is a 2-D array, we can access any element arr[i][j] of the array using the pointer expression *(*(arr + i) + j). Now we’ll see how this expression can be derived.
    Let us take a two dimensional array arr[3][4]:
    int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };



    Since memory in computer is organized linearly it is not possible to store the 2-D array in rows and columns. The concept of rows and columns is only theoretical, actually a 2-D array is stored in row major order i.e rows are placed next to each other. The following figure shows how the above 2-D array will be stored in memory.

    Each row can be considered as a 1-D array, so a two-dimensional array can be considered as a collection of one-dimensional arrays that are placed one after another. In other words we can say that a 2-D dimensional arrays that are placed one after another. So here arr is an array is an array of 3 elements where each element is a 1-D array of 4 integers.
    We know that the name of an array is a constant pointer that points to 0th 1-D array and contains address 5000. Since arr is a ‘pointer to an array of 4 integers’, according to pointer arithmetic the expression arr + 1 will represent the address 5016 and expression arr + 2 will represent address 5032.
    So we can say that arr points to the 0th 1-D array, arr + 1 points to the 1st 1-D array and arr + 2 points to the 2nd 1-D array.


    In general we can write:
    arr + i  Points to ith element of arr ->
    Points to ith 1-D array
    • Since arr + i points to ith element of arr, on dereferencing it will get ith element of arr which is of course a 1-D array. Thus the expression *(arr + i) gives us the base address of ith 1-D array.
    • We know, the pointer expression *(arr + i) is equivalent to the subscript expression arr[i]. So *(arr + i) which is same as arr[i] gives us the base address of ith 1-D array.

    In general we can write:
    *(arr + i)  -  arr[i]  -  Base address of ith 1-D array -> Points to 0th element of ith 1-D array
    Note: Both the expressions (arr + i) and *(arr + i) are pointers, but their base type are different. The base type of (arr + i) is ‘an array of 4 units’ while the base type of *(arr + i) or arr[i] is int.
    • To access an individual element of our 2-D array, we should be able to access any jth element of ith 1-D array.
    • Since the base type of *(arr + i) is int and it contains the address of 0th element of ith 1-D array, we can get the addresses of subsequent elements in the ith 1-D array by adding integer values to *(arr + i).
    • For example *(arr + i) + 1 will represent the address of 1st element of 1stelement of ith 1-D array and *(arr+i)+2 will represent the address of 2nd element of ith 1-D array.
    • Similarly *(arr + i) + j will represent the address of jth element of ith 1-D array. On dereferencing this expression we can get the jth element of the ith 1-D array.


    filter_none edit
    play_arrow
    brightness_4
    // C program to print the values and 
    // address of elements of a 2-D array
    #include<stdio.h>
      
    int main()
    {
      int arr[3][4] = {
                        { 10, 11, 12, 13 },
                        { 20, 21, 22, 23 },
                        { 30, 31, 32, 33 }
                      };
      int i, j;
      for (i = 0; i < 3; i++)
      {
        printf("Address of %dth array = %p %p\n"
                        i, arr[i], *(arr + i));
          
        for (j = 0; j < 4; j++)
          printf("%d %d ", arr[i][j], *(*(arr + i) + j));
        printf("\n");
      }
      
      return 0;
    }
    Output:
    Address of 0th array = 0x7ffe50edd580 0x7ffe50edd580
    10 10 11 11 12 12 13 13 
    Address of 1th array = 0x7ffe50edd590 0x7ffe50edd590
    20 20 21 21 22 22 23 23 
    Address of 2th array = 0x7ffe50edd5a0 0x7ffe50edd5a0
    30 30 31 31 32 32 33 33
    
  2. Pointers and Three Dimensional Arrays
    In a three dimensional array we can access each element by using three subscripts. Let us take a 3-D array-

    int arr[2][3][2] = { {{5, 10}, {6, 11}, {7, 12}}, {{20, 30}, {21, 31}, {22, 32}} };
    We can consider a three dimensional array to be an array of 2-D array i.e each element of a 3-D array is considered to be a 2-D array. The 3-D array arr can be considered as an array consisting of two elements where each element is a 2-D array. The name of the array arr is a pointer to the 0th 2-D array.

    Thus the pointer expression *(*(*(arr + i ) + j ) + k) is equivalent to the subscript expression arr[i][j][k].
    We know the expression *(arr + i) is equivalent to arr[i] and the expression *(*(arr + i) + j) is equivalent arr[i][j]. So we can say that arr[i] represents the base address of ith 2-D array and arr[i][j] represents the base address of the jth 1-D array.
    filter_none edit
    play_arrow
    brightness_4
    // C program to print the elements of 3-D
    // array using pointer notation
    #include<stdio.h>
    int main()
    {
      int arr[2][3][2] = {
                           {
                             {5, 10},
                             {6, 11},
                             {7, 12},
                           },
                           {
                             {20, 30},
                             {21, 31},
                             {22, 32},
                           }
                         };
      int i, j, k;
      for (i = 0; i < 2; i++)
      {
        for (j = 0; j < 3; j++)
        {
           for (k = 0; k < 2; k++)
             printf("%d\t", *(*(*(arr + i) + j) +k));
           printf("\n");
        }
      }
      
      return 0;
    }
    Output:
    5    10    
    6    11    
    7    12    
    20    30    
    21    31    
    22    32
    The following figure shows how the 3-D array used in the above program is stored in memory.
Subscripting Pointer to an Array
Suppose arr is a 2-D array with 3 rows and 4 columns and ptr is a pointer to an array of 4 integers, and ptr contains the base address of array arr.
int arr[3][4] = {{10, 11, 12, 13}, {20, 21, 22, 23}, {30, 31, 32, 33}};
int (*ptr)[4];
ptr = arr;

Since ptr is a pointer to an array of 4 integers, ptr + i will point to ith row. On dereferencing ptr + i, we get base address of ith row. To access the address of jth element of ith row we can add j to the pointer expression *(ptr + i). So the pointer expression *(ptr + i) + j gives the address of jth element of ith row and the pointer expression *(*(ptr + i)+j) gives the value of the jth element of ith row.
We know that the pointer expression *(*(ptr + i) + j) is equivalent to subscript expression ptr[i][j]. So if we have a pointer varible containing the base address of 2-D array, then we can access the elements of array by double subscripting that pointer varible.
filter_none edit
play_arrow
brightness_4
// C program to print elements of a 2-D array 
// by scripting a pointer to an array 
#include<stdio.h>
  
int main()
{
  int arr[3][4] = { 
                    {10, 11, 12, 13}, 
                    {20, 21, 22, 23}, 
                    {30, 31, 32, 33} 
                  };
  int (*ptr)[4];
  ptr = arr;
  printf("%p %p %p\n", ptr, ptr + 1, ptr + 2);
  printf("%p %p %p\n", *ptr, *(ptr + 1), *(ptr + 2));
  printf("%d %d %d\n", **ptr, *(*(ptr + 1) + 2), *(*(ptr + 2) + 3));
  printf("%d %d %d\n", ptr[0][0], ptr[1][2], ptr[2][3]);
  return 0;
}
Output:
0x7ffead967560 0x7ffead967570 0x7ffead967580
0x7ffead967560 0x7ffead967570 0x7ffead967580
10 22 33
10 22 33

 

 

Difference between pointer and array:

Most of the time, pointer and array accesses can be treated as acting the same, the major exceptions being:
1) the sizeof operator
o sizeof(array) returns the amount of memory used by all elements in array
o sizeof(pointer) only returns the amount of memory used by the pointer variable itself
2) the & operator
o &array is an alias for &array[0] and returns the address of the first element in array
o &pointer returns the address of pointer
3) a string literal initialization of a character array
o char array[] = “abc” sets the first four elements in array to ‘a’, ‘b’, ‘c’, and ‘\0’
o char *pointer = “abc” sets pointer to the address of the “abc” string (which may be stored in read-only memory and thus unchangeable)
4) Pointer variable can be assigned a value whereas array variable cannot be.


int a[10];
int *p; 
p=a; /*legal*/
a=p; /*illegal*/ 
5) Arithmetic on pointer variable is allowed.
p++; /*Legal*/
a++; /*illegal*/ 




all about enums


Enumeration (or enum) is a user defined data type in C. It is mainly used to assign names to integral constants, the names make a program easy to read and maintain.

enum State {Working = 1, Failed = 0};
The keyword ‘enum’ is used to declare new enumeration types in C and C++. Following is an example of enum declaration.
// The name of enumeration is "flag" and the constant
// are the values of the flag. By default, the values
// of the constants are as follows:
// constant1 = 0, constant2 = 1, constant3 = 2 and
// so on.
enum flag{constant1, constant2, constant3, ....... };
Variables of type enum can also be defined. They can be defined in two ways:
// In both of the below cases, "day" is
// defined as the variable of type week.

enum week{Mon, Tue, Wed};
enum week day;

// Or

enum week{Mon, Tue, Wed}day;
filter_none
edit
play_arrow
brightness_4
// An example program to demonstrate working
// of enum in C
#include<stdio.h>
 
enum week{Mon, Tue, Wed, Thur, Fri, Sat, Sun};
 
int main()
{
    enum week day;
    day = Wed;
    printf("%d",day);
    return 0;
}
Output:


2
In the above example, we declared “day” as the variable and the value of “Wed” is allocated to day, which is 2. So as a result, 2 is printed.
Another example of enumeration is:
filter_none
edit
play_arrow
brightness_4
// Another example program to demonstrate working
// of enum in C
#include<stdio.h>
 
enum year{Jan, Feb, Mar, Apr, May, Jun, Jul, 
          Aug, Sep, Oct, Nov, Dec};
 
int main()
{
   int i;
   for (i=Jan; i<=Dec; i++)      
      printf("%d ", i);
       
   return 0;
}
Output:
0 1 2 3 4 5 6 7 8 9 10 11
In this example, the for loop will run from i = 0 to i = 11, as initially the value of i is Jan which is 0 and the value of Dec is 11.
 

Interesting facts about initialization of enum.
1. Two enum names can have same value. For example, in the following C program both ‘Failed’ and ‘Freezed’ have same value 0.
filter_none
edit
play_arrow
brightness_4
#include <stdio.h>
enum State {Working = 1, Failed = 0, Freezed = 0};
 
int main()
{
   printf("%d, %d, %d", Working, Failed, Freezed);
   return 0;
}
Output:
1, 0, 0


2. If we do not explicitly assign values to enum names, the compiler by default assigns values starting from 0. For example, in the following C program, sunday gets value 0, monday gets 1, and so on.
filter_none
edit
play_arrow
brightness_4
#include <stdio.h>
enum day {sunday, monday, tuesday, wednesday, thursday, friday, saturday};
 
int main()
{
    enum day d = thursday;
    printf("The day number stored in d is %d", d);
    return 0;
}
Output:
The day number stored in d is 4


3. We can assign values to some name in any order. All unassigned names get value as value of previous name plus one.


filter_none
edit
play_arrow
brightness_4
#include <stdio.h>
enum day {sunday = 1, monday, tuesday = 5,
          wednesday, thursday = 10, friday, saturday};
 
int main()
{
    printf("%d %d %d %d %d %d %d", sunday, monday, tuesday,
            wednesday, thursday, friday, saturday);
    return 0;
}
Output:
1 2 5 6 10 11 12


4. The value assigned to enum names must be some integeral constant, i.e., the value must be in range from minimum possible integer value to maximum possible integer value.


5. All enum constants must be unique in their scope. For example, the following program fails in compilation.
filter_none
edit
play_arrow
brightness_4
enum state  {working, failed};
enum result {failed, passed};
 
int main()  { return 0; }
Output:
Compile Error: 'failed' has a previous declaration as 'state failed'


Exercise:
Predict the output of following C programs
Program 1:
filter_none
edit
play_arrow
brightness_4
#include <stdio.h>
enum day {sunday = 1, tuesday, wednesday, thursday, friday, saturday};
 
int main()
{
    enum day d = thursday;
    printf("The day number stored in d is %d", d);
    return 0;
}


Program 2:
filter_none
edit
play_arrow
brightness_4
#include <stdio.h>
enum State {WORKING = 0, FAILED, FREEZED};
enum State currState = 2;
 
enum State FindState() {
    return currState;
}
 
int main() {
   (FindState() == WORKING)? printf("WORKING"): printf("NOT WORKING");
   return 0;
}


Enum vs Macro
We can also use macros to define names constants. For example we can define ‘Working’ and ‘Failed’ using following macro.
filter_none


brightness_4
#define Working 0
#define Failed 1
#define Freezed 2
There are multiple advantages of using enum over macro when many related named constants have integral values.
a) Enums follow scope rules.
b) Enum variables are automatically assigned values. Following is simpler
filter_none


brightness_4
enum state  {Working, Failed, Freezed};

Ref:
https://www.geeksforgeeks.org/enumeration-enum-c/
https://www.geeksforgeeks.org/static-const-vs-define-vs-enum/

typdefs for pointer and function pointer and enum and struct

typedef in function pointer:




int add(int a, int b)
{
    return (a+b);
}

typedef int (*add_integer)(int, int); //declaration of function pointer

int main()
{
    add_integer addition = add; //typedef assigns a new variable i.e. 
                                //"addition" to original function "add"
    int c = addition(11, 11);   //calling function via new variable
    printf("%d",c);
    return 0;
}



Ref: https://stackoverflow.com/questions/1591361/understanding-typedefs-for-function-pointers-in-c


typedef in pointer:


The typedef may be used in declaration of a number of pointers of the same type. It does not change the type, it only creates a synonym, i.e., another name for the same type as illustrated below.
typedef float* FP; // Now FP represents float*
float x,y,z;
FP px =&x, py = &y, pz = &z ; // Use of FP
In the above code px, py, and pz are pointers initialized with addresses of x, y, and z respectively.
Illustrates use of typedef in pointer declaration.


#include <stdio.h>
void main()
{
   typedef double* Dp;
   double x = 10.5,y = 8.6, z = 12.5;
   Dp px = &x , py = &y, pz = &z;
   clrscr();
   printf("x = %.3lf,\t *px =  %.3lf\t px = %p \n", x, *px, px);
   printf("y = %.3lf,\t *py =  %.3lf\t py = %p \n", y, *py, py);
   printf("z = %.3lf,\t *pz =  %.3lf\t pz = %p \n", z, *pz, pz);
} 


Reference from:
http://ecomputernotes.com/what-is-c/function-a-pointer/typedef-in-pointer

typedef in enum:




way 1: 
enum State {Working = 1, Failed = 0}; 
way 2: 
typedef enum {false, true} boolean;
boolean error = false;
         


Reference from:
http://ecomputernotes.com/what-is-c/function-a-pointer/typedef-in-pointer

typedef in struct:



#include <stdio.h>
#include <string.h>
 
typedef struct Books {
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
} Book;
 
int main( ) {

   Book book;
 
   strcpy( book.title, "C Programming");
   strcpy( book.author, "Nuha Ali"); 
   strcpy( book.subject, "C Programming Tutorial");
   book.book_id = 6495407;
 
   printf( "Book title : %s\n", book.title);
   printf( "Book author : %s\n", book.author);
   printf( "Book subject : %s\n", book.subject);
   printf( "Book book_id : %d\n", book.book_id);

   return 0;
}


Ref: https://www.tutorialspoint.com/cprogramming/c_typedef.htm




Saturday, June 1, 2019

how to put break points for static functions

 
 
functions declared "static" in the code don't show up in GDB
backtraces when the code was compiled at -O2 and above, nor can you
set breakpoints on them.  You can however set a breakpoint in the
static function if you know the file name + line number.

Sample code:
#include <stdio.h>
void f3 (const char *a)
{
 fprintf (stderr, "f3: '%s'\n", a);
}
static void f2 (const char *a)
{
 f3 (a);
}
int main (int argc, char **argv)
{
 f2 ("bork");
}

So, "break f2" won't work, but "break foo.c:8" will work to break in
f2().  This greatly hampers the ability to debug programs that use
static functions since you cannot see or switch to a frame that's static.
 
 
 
or 
 
1
Assuming the routine really exists as you'd expect (i.e., not optimized away or inlined) - I've used a couple approaches in situations like this:
Assembly breakpoint
  • let's say you want to set a breakpoint at static function foo(). Find code that calls foo() - let's say bar() calls foo(). Where bar() calls foo(), set a breakpoint.
  • run until you hit the breakpoint where bar() calls foo(). step at the assembly level. This should put you at the first instruction of foo(). Note that you might have to step through a few instructions if there are parameters being passed - hopefully you know what a branch / subroutine call looks like in your architecture.
  • Set an assembly breakpoint when you land at the first instruction of foo().
Function pointer
I've also worked around this by initializing a function pointer with foo()'s address. When system is running, read the function pointer in the debugger. Get foo()'s address. Set breakpoint based on this address.
Note that in these cases you might not have interleaved source, though.
 
 
 
 
 
Reference taken from:
 
https://bugzilla.redhat.com/show_bug.cgi?id=136536
https://stackoverflow.com/questions/8759737/how-do-i-set-a-vxworks-breakpoint-on-a-c-static-function