1

I have following code. structure emp_ has five elements and all of its first four members could be printed with print_emp_details() function which takes a pointer to a emp_ struct. Given only a offset and a pointer to a particular field, start_address(glthread_node_t *node_t) should return (after casting) the start address of the struct emp_ which is then pass into print_emp_details(). I am getting gibberish printf output from print_emp_details() and couldn't find what I am doing wrong. The offsetValue is only thing I am getting right.

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include "glthread.h"


#define glthread_node_init(glnode)  \
    glnode->left = NULL;            \
    glnode->right = NULL;


#define offset(struct_name, fld_name) \
  (unsigned int)&(((struct_name *)0)->fld_name)

typedef struct glthread_node_ {
    struct glthread_node_ *left;
    struct glthread_node_ *right;
} glthread_node_t; 

typedef struct glthread_ {
    glthread_node_t *head;
    unsigned int offset;
} glthread_t;



typedef struct emp_ {
    char name[30];
    unsigned int salary;
    char designation[30];
    unsigned int emp_id;
    glthread_node_t glnode;
} emp_t;


struct emp_ *
start_address(glthread_node_t *node_t){
  unsigned int offsetValue;
  offsetValue=offset(emp_t,glnode);
  printf("offset = %d\n", offsetValue);
  return (struct emp_*)(node_t-offsetValue);
}

void
print_emp_details(emp_t *emp){

    printf("Employee name = %s\n", emp->name);
    printf("salary = %u\n", emp->salary);
    printf("designation = %s\n", emp->designation);
    printf("emp_id = %u\n", emp->emp_id);
}

void
init_glthread(glthread_t *glthread, unsigned int offset){

    glthread->head = NULL;
    glthread->offset = offset;
}

int
main(int argc, char **argv){
  emp_t *emp1=calloc(1,sizeof(emp_t));
  strncpy(emp1->name,"Harris", strlen("Harris"));
  emp1->salary= 100;
  strncpy(emp1->designation,"HR",strlen("HR"));
  emp1->emp_id=13;
  glthread_node_init((&emp1->glnode));
  print_emp_details(start_address(&emp1->glnode));
  return 0;
}

Output:

offset = 72
Employee name = ?T??
salary = 0
designation = 
emp_id = 1920169263
H.Jamil
  • 73
  • 8

1 Answers1

2

The problem is at the end of start_address:

return (struct emp_*)(node_t-offsetValue);

When you add or subtract a value from a pointer, it results in a pointer increased/decreated by that value times the size of the type the pointer points to. It is done this way to make array indexing work.

You need to cast the pointer to char * to add/subtract single byte values:

return (struct emp_*)((char *)node_t-offsetValue);
dbush
  • 205,898
  • 23
  • 218
  • 273