C/C++


C/C++: Get a random number that is in a specific range 1

Assuming you need to generate a random number that is in a specified range, you can do the following:


//int rand(void) creates a pseudo-random number in the range of 0 to RAND_MAX
//RAND_MAX is defined in stdlib.h and is the largest number rand will return (same as INT_MAX).
const int new_number = (rand() % (maximum_number + 1 - minimum_number)) + minimum_number;

The above code first creates a pseudo-random number that is in the range of [0, RAND_MAX].
Then it will divide it with the width (+1) of the range we want to use (maximum_number + 1 - minimum_number) and get the remainder (modulo).
The modulo will be in the range of [0, maximum_number - minimum_number], so we add to it the value of minimum_number to shift the result to the proper range.
This solution, as demonstrated in the example below, works for negative ranges as well.

Full example of generating 100000 random numbers that are all in the range [-31, 32].

const int maximum_number = 31;
const int minimum_number = -32;
unsigned int i;
for (i = 0; i <= 100000; i++) {
	const int new_number = (rand() % (maximum_number + 1 - minimum_number)) + minimum_number;
	printf("%d\n", new_number);
}

C/C++: Set and Get the name of a pthread

Naming a pthread using meaningful names, can be a very useful feature for debugging multi-threaded applications as it can make your logs very informative.
For this reason, we are presenting two examples demonstrating the use of names in pthreads.

  • [download id=”3786″]
  • [download id=”3788″]

Example 1: The pthread decides for its name

The following code, creates a pthread which later, it will give itself a meaningful name.

[download id=”3786″]


// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    const int setname_rv = pthread_setname_np(thread_info->thread_id, "Tom Hanks");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and I gave me my name by myself\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }
    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

[download id=”3786″]

Example 2: The parent decides for the pthread name

The next code, creates a pthread and the parent gives the thread a meaningful name.

[download id=”3788″]


// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>
// #include <unistd.h> is needed for the resolution of unsigned int sleep(unsigned int seconds);
#include <unistd.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    //Added an artificial delay for the sake of the example.
    //Making sure the parent thread gave the pthread a name.
    sleep(1);

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and my parent gave me my name\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }

    const int setname_rv = pthread_setname_np(thread_info.thread_id, "Bob Marley");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

[download id=”3788″]


How does the expression, “*pointer++” evaluate?

*pointer++ will increment the position of the pointer first but it will return the value that was pointed before the position of the pointer changed.

*pointer++ is equivalent to *(pointer++). This happens because the postfix ++ and -- operators have higher precedence than the indirection (dereference).
You can read more about the precedence order at this very helpful article at Wikipedia: https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

To increment the value pointed to by pointer, use (*pointer)++.

To increment the position of the pointer and return the value that is pointed after the position of the pointer changed use *++pointer.

Examples

The following example will increment the position of the pointer but return the value that was originally pointed.
By the end of the following block, pointer will point to position 1 and the value variable will have the value 11.


const unsigned int values[] = {11, 12, 14, 18};
const unsigned int *pointer = values;
const unsigned int value = *pointer++;

The following example will increment the position of the pointer and return the value that the new position is pointing to.
By the end of the following block, pointer will point to position 1 and the value variable will have the value 12.


const unsigned int values[] = {11, 12, 14, 18};
const unsigned int *pointer = values;
const unsigned int value = *++pointer;


C/C++: Full example using a linked list with custom struct

The following code is an example that presents some basic functionality on simply linked lists. Specifically, it presents how to add an element to an empty list and then how to add more elements either to the start (prepend) or to the end (append) of the list.

[download id=”2444″]

We assume that our structure holds an integer and a dynamically created string, which we free after pop.

[download id=”2444″]

 

Source file (list_helpers.c)

#include <malloc.h>
#include "list_helpers.h"

void append(node_t **head, element_t *element) {

  struct node_t *new = malloc(sizeof(node_t));
  new->element = element;
  new->next = NULL;

  if (*head == NULL) {
    *head = new;
    return;
  }

  struct node_t *current = *head;

  while (current->next != NULL) {
    current = current->next;
  }

  current->next = new;
  return;
}

void prepend(node_t **head, element_t *element) {
  struct node_t *new = malloc(sizeof(node_t));

  new->element = element;
  new->next = *head;
  *head = new;
}

element_t *pop(node_t **head) {

  node_t *next = NULL;

  if (*head == NULL) {
    return NULL;
  }

  next = (*head)->next;
  element_t *element = (*head)->element;
  free(*head);
  *head = next;

  return element;
}

void clear(node_t **head) {
  element_t *current = pop(head);
  while (current != NULL) {
    free(current->username);
    free(current);
    current = pop(head);
  }
}

Header file (list_helpers.h)

#ifndef GM_S_LITTLE_HELPERS_LIST_HELPERS_H
#define GM_S_LITTLE_HELPERS_LIST_HELPERS_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct element_t element_t;
struct element_t {
  //We add random members to the element struct for the sake of the example
  char *username;
  unsigned int server;
};

typedef struct node_t node_t;
struct node_t {
  element_t *element;
  node_t *next;
};

void append(node_t **head, element_t *element);

void prepend(node_t **head, element_t *element);

element_t *pop(node_t **head);

void clear(node_t **head);

#ifdef __cplusplus
}
#endif

#endif //GM_S_LITTLE_HELPERS_LIST_HELPERS_H

Usage example (main.cpp)

#include <iostream>
#include "list_helpers.h"

element_t *create_user(const unsigned int server, const char *username) {

  element_t *user = (element_t *) malloc(sizeof(element_t));
  user->server = server;

  //For the sake of the example we used snprintf.
  //Upon successful return, snprintf returns the number of characters printed (excluding the null byte used to end output to strings).
  //For that reason we add one at the end of the length.
  const int length = snprintf(NULL, 0, "%s", username) + 1;
  user->username = (char *) malloc((sizeof(char) * length));
  snprintf(user->username, (size_t) length, "%s", username);
  return user;
}

int main(int argc, char *argv[]) {

  node_t *head = NULL;

  //Add the first element to the linked list
  append(&head, create_user(10, "xeirwn"));

  //Add the second element to the end of the linked list
  append(&head, create_user(12, "test"));

  //Add the third element to the end of the linked list
  append(&head, create_user(14, "banana"));

  //Add the fourth element to the beginning of the linked list
  prepend(&head, create_user(8, "apple"));

  //Popping each one to process it and then free it
  //Clearing the list
  element_t *current = pop(&head);
  while (current != NULL) {

    printf("%s\t%u\n", current->username, current->server);
    free(current->username);
    free(current);
    current = pop(&head);
  }

  //Safely clear the list. In this specific scenario it will have 0 side effects as the list was cleared above
  clear(&head);
  return 0;
}

[download id=”2444″]