can anyone tell me why this program is printing 3 as the output or tell the functionality of the program.
#include<stdio.h>
#include<stdlib.h>
struct st
{
int a;
int b;
};
void func(struct st*);
int main()
{
struct st ab={128,768};
struct st *pq=&ab;
func(pq);
return 0;
}
void func(struct st *p)
{
char *pt;
p->a=768;
p->b=128;
pt=(char*)p;
printf("----%d\n",*(++pt));
}
You have stored 768 in first member of struct st, so address at start of struct has 0x00000300(considering 4 bytes of int) in memory, when viewed as little endian stream it will look as 0x00030000
You have stored its pointer in ptr which is char * which now points to value 0x00, ++ptr will point to next value ie 0x03
Related
I have many programs where structs are defined. And each time, I have to create a function to print the members. For example,
typedef struct {
char name[128];
char address[1024];
int zip;
} myStruct;
void printMyStruct(myStruct myPeople) {
printf("%s\n",myPeople.name);
printf("%s\n",myPeople.address);
printf("%d\n",myPeople.zip);
}
int main()
{
myStruct myPeople={"myName" , "10 myStreet", 11111};
printMyStruct(myPeople);
}
I know that reflection is not supported in C. And so, I write these printing functions for each struct I defined.
But, I wonder if it exists any tricks to generate automatically these printing functions. I would understand that I have to modify a little bit these functions. But, if a part of the job is done automatically, it would be great.
(This example is simple, sometimes struct are nested or I have array of structs or some fields are pointers, ...)
You can of-course print structs, but expect a lot of non-readable output:
#include <stdio.h>
#include <ctype.h>
struct example {
int x;
int y;
char c;
};
#define NOT_PRINTABLE "Not Printable"
void print_structure(const char *structure, size_t size) {
for (size_t i = 0; i < size; i++) {
printf("%ld)\t%.2X: %.*s\n", i, structure[i],
(isprint(structure[i]) ? 1 : sizeof(NOT_PRINTABLE) - 1),
(isprint(structure[i]) ? &structure[i] : NOT_PRINTABLE));
}
}
int main(int argc, char **argv) {
struct example a;
a.x = 5;
a.y = 6;
a.c = 'A';
print_structure((char *)&a, sizeof(struct example));
return 0;
}
But the issue is that, it will print the structs as it is represented in memory. So 4 byte (32 bit) integer 1 will be represented with 4 bytes, not the char '1'.
And due to the way pointers work, you cannot make out if a member is a pointer or a non-pointer.
Another issue is that structures have padding to help with alignment, and better/efficent use of memory. So you would see a lot of 0x00 in the middle.
Remember that C is a compiled language.
let's consider to use https://copilot.github.com/. it's great.
this is what i have with copilot
typedef struct {
char name[128];
char address[1024];
int zip;
} myStruct;
//print struct myStruct >> auto generate by codepilot after you type a comment `print struct myStruct`
void printStruct(myStruct *s) {
printf("name: %s\n", s->name);
printf("address: %s\n", s->address);
printf("zip: %d\n", s->zip);
}
I have a simple C program of below type
#include<stdio.h>
struct test{
char a;
char b;
char c;
char d;
int e;
};
void main() {
struct test mem = {0xa, 0xb, 0xc, 0xd, 0xef12};
long int *tmp = (long int *)(&mem.a);
printf("Struct in binary %p : 0x%lx\n", &mem.a, *tmp);
printf("Printing only a member %p : 0x%x\n", &(mem.e), *(int *)(&(mem.e)));
}
The output of above program is as below on a Big endian machine :
Struct in binary 0x7ffc1206abc0 : 0xef120d0c0b0a
Printing only a member 0x7ffc1206abc4 : 0xef12
The question is that why is the raw output of the struct in the reverse order of its members' values?
The address of 'member e' is still 4 bytes from the start of the struct base address..!
Hey all I'm having some trouble diagnosing the reason for an error in printing an array of structures in C.
In a separate header file (call it header.h) I have the following typedef'd structure:
typedef struct instruction prog;
struct instruction{
char kind;
char op[4];
};
For my main programing task I want to read from a file a series of what are supposed to be instructions consisting of a type character (the variable kind above) and an instruction consisting of four integers (listed as op above). Examples include R 1004 E 1008, etc. I can read the data in just fine but it seems to be storing things improperly. I wrote the following test code to see if I could find the error but I was still getting the same issue. My goal is to store these as an array of instructions where, using the parlance of the code below, mem[i].kind = 'R' and mem[i].op =1004`.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include "header.h"
void memFill(prog *P, int x);
void memPrint(prog *P, int x);
int main(){
prog mem[10];
memFill(&mem[0], 10);
memPrint(&mem[0], 10);
return 0;
}
void memFill(prog *P, int x){
char *v = "1004";
for(int i = 0; i< x; i++){
P->kind = 'R';
strcpy(P->op, v);
P++;
}
}
void memPrint(prog *P, int x){
for(int i = 0; i <x; i++){
printf("%c %s\n",P->kind, P->op);
P++;
}
}
This is giving me output that looks like this:
R 1004R1004R1004R1004R1004R1004R1004R1004R1004R1004
R 1004R1004R1004R1004R1004R1004R1004R1004R1004
R 1004R1004R1004R1004R1004R1004R1004R1004
R 1004R1004R1004R1004R1004R1004R1004
R 1004R1004R1004R1004R1004R1004
R 1004R1004R1004R1004R1004
R 1004R1004R1004R1004
R 1004R1004R1004
R 1004R1004
R 1004
The reason this is weird is that identical pointer arithmetic has given just fine results with a similar structure. What's going on here? What am I missing?
Buffer overflow on char op[4], then Undefined_behavior
To be able to store "1004" it have to be 5 bytes long to have space for NULL terminator.
struct instruction{
char kind;
char op[5];
};
Literal string "1004" is '1', '0', '0', '4', '\0'
You forgot to give space for the string ending null.
Fix your struct declaration to this:
struct instruction{
char kind;
char op[5];
};
And it will work.
You can also simplify declaration this way:
typedef struct instruction{
char kind;
char op[5];
} prog;
I have called a function with seven parameters from main
find_sync(es_data + (loop_count * size) + chunk_bytes_counter,
size - chunk_bytes_counter, &sync_index, &flag,
&sync_length, &chunk_bytes_counter, &total_bytes_counter);
in function.c:
void find_sync(char data[], size_t size, unsigned int *sync_index, int *flag, unsigned int *sync_length, unsigned int *chunk_bytes_counter, unsigned int *total_bytes_counter)
prototype in header file:
extern void find_sync(char data[], size_t size, unsigned int *sync_index, int *flag, unsigned int *sync_length, unsigned int *bytes_counter, unsigned int *total_bytes_counter);
Now, my question is, how can i declare all these 7 parameters in a structure, so that i can only pass one structure variable.
Begin by declaring the struct:
struct find_sync_parameters {
char* data;
size_t size;
unsigned int *sync_index;
int *flag;
unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
}
Then change your function signature either to:
void find_sync(struct find_sync_parameters param)
Or to
void find_sync(struct find_sync_parameters *param)
In the first case the whole struct will be pushed onto the stack before transferring control to find_sync. On the second case only a pointer to the struct (stored elsewhere) will be pushed.
There are advantages and drawbacks in each one. When passing a pointer note that the function can change the contents (this can be positive: for returning values directly inside the struct; also can be negative: the caller cannot be sure if its data were changed or not). If the struct is too big (not your case), then pushing everything onto the stack can take a significant amount of time and become a performance hit.
Inside the function you use it either with '.' (dot, the first case) or '->' (arrow, the second case) operator.
To call it:
struct find_sync_parameters p = { ... };
find_sync(p); // first case
find_sync(&p); // second case
If you find it annoying to type struct find_sync_parameters everytime you can define a new type with typedef:
typedef struct find_sync_parameters find_sync_parameters;
Or in one line (struct and typedef definitions):
typedef struct find_sync_parameters {
...
} find_sync_parameters;
Or even without struct name (anonymous struct)
typedef struct {
...
} find_sync_parameters;
In this last case you cannot reference the struct itself inside the struct (the case, for example, with linked list nodes).
Just put in structure .
struct pars_t
{
char data[];
size_t size; unsigned int *sync_index;
int *flag; unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
} pars;
and then call foo (pars_t par)
You can create a struct (and typedef it at the same time, to make it usable without saying "struct" every time) like so:
typedef struct _find_sync_str{
char* data;
size_t size;
unsigned int *sync_index;
int *flag;
unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
} find_sync_str
Then you can list the function as:
void find_sync(find_sync_str f);
I am going to suggest:
struct find_sync_struct {
char* data;
size_t size;
unsigned int sync_index;
int flag;
unsigned int sync_length;
unsigned int bytes_counter;
unsigned int total_bytes_counter;
};
Change the input argument of find_sync to:
void find_sync(struct find_sync_struct* strPtr);
Call the function using:
struct find_sync_struct str;
// Set str.data to something suitable.
// ....
find_sync(&str);
Here is a simple example demonstrating how to pass a structure to a function:
#include<stdio.h>
#include<conio.h>
//-------------------------------------
struct Example
{
int num1;
int num2;
}s[3];
//-------------------------------------
void accept(struct Example *sptr)
{
printf("\nEnter num1 : ");
scanf("%d",&sptr->num1);
printf("\nEnter num2 : ");
scanf("%d",&sptr->num2);
}
//-------------------------------------
void print(struct Example *sptr)
{
printf("\nNum1 : %d",sptr->num1);
printf("\nNum2 : %d",sptr->num2);
}
//-------------------------------------
void main()
{
int i;
clrscr();
for(i=0;i<3;i++)
accept(&s[i]);
for(i=0;i<3;i++)
print(&s[i]);
getch();
}
I'm testing the judy arrays implementation on ubuntu 11.10 "libjudy-dev".
I'm encounter with a strange behavior, possible bug. related to the size of val and the key.
In the example, if i use the struct TEST with only 1 int with large keys works, but if i use the 10 int struct with the same key it doesn't, the 10 int struct works ok with small keys.
judy manpage
In the man page said that the string can be any size.
#include <stdio.h>
#include <string.h>
#include <Judy.h>
/*struct TEST {
unsigned int size9;
};*/
struct TEST {
unsigned int size0;
unsigned int size1;
unsigned int size2;
unsigned int size3;
unsigned int size4;
unsigned int size5;
unsigned int size6;
unsigned int size7;
unsigned int size8;
unsigned int size9;
};
int main()
{
struct TEST *val;
char key[1024];
Pvoid_t array = NULL;
//strcpy(key, "0123456789_0123456789");
strcpy(key, "0123456789_0123456789_0123456789");
JSLI(val, array, key);
val->size9 = 10;
val = NULL;
JSLG(val, array, key);
if(val == NULL) {
printf("NULL\n");
} else {
printf("%u\n", val->size9);
}
return 0;
}
JudySL "maps" a string to a word in RAM. This word is used as a "word_t" or a "pointer to more memory". The routines return (val in your case) a pointer to the word available for your use.
Your code makes that pointer (val) a pointer to a struct of greater size than one word -- thus
destroying part of the internal Judy data structure with the statement "val->size9 = 10;".
Keep in mind that the "key" is a string, and the PValue is a pointer to an object of size word. If you want *PValue to point to struct TEST and it is bigger than a word_t then memory must be allocated for it. Your test program seems to want to map a string to a struct TEST--
struct TEST is bigger than a word_t.
Doug Baskins