Need logic to allocate memory for nested structures - data-structures

I am not able to allocate memory for nested structures using pointers.
What syntax should I use to allocate the memory for lots of structures that have pointers to other structures? How should I go about accessing the values in the structures once the memory is allocated?
struct A {
int *a;
struct B *b;
};
struct B {
int *b;
struct C *c;
};
struct C {
int *c;
struct D *d;
};
struct D {
int *d;
};
int main(int argc, const char* argv[]) {
struct A* foo;
/* Structure allocation */
/* use of structures */
}
I can't go beyond 2 nested structures. Beyond that I start getting Segmentation fault.
I tried something like this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct file f1;
typedef struct command c1;
typedef struct arguments a1;
typedef struct ccity ccity;
typedef struct csub csub;
struct arguments {
char *argname;
struct arguments *next;
};
struct command {
char *cmdname;
struct arguments *args;
};
struct file{
int fileid;
char *filename;
struct command *cmd;
};
struct sub{
char *subname;
};
struct city {
char *city_name;
struct sub *s11;
};
struct road{
char *name;
struct city *next_city;
};
int main()
{
char name[] = "HELLO ";
struct file *f1;
struct city *c1 = NULL;
struct road *r1 = NULL;
struct sub *s1 = NULL;
printf("HELOOOOOOOOO");
f1->filename;
f1 = malloc(10*sizeof(struct file ));
f1->filename = (char *)malloc(10*sizeof(char *));
c1 = malloc(sizeof(c1));
r1 = malloc(sizeof(r1));
s1 = malloc(sizeof(s1));
r1->name = malloc(100*sizeof(char *));
r1->next_city = malloc(100*sizeof(r1->next_city));
c1->city_name = malloc(100*sizeof(char *));
c1->s11 = malloc(100*sizeof(c1->s11));
c1->s11->subname = calloc(120,sizeof(char*));
(*c1).s11->subname = "text";
(*r1).next_city->s11->subname =
malloc(10 * sizeof((*r1).next_city->s11->subname));
strncpy((*r1).next_city->s11->subname,"sant",4);
r1->name = malloc(sizeof(char *));
c1->city_name = malloc(sizeof(char *));
r1->next_city = malloc(sizeof(char *));
r1->next_city->city_name = "Hello";
/*strcpy(f1->filename,"file1");
printf("name is %s\n",(f1->filename));
c1->cmdname = (char *)malloc(10*sizeof(c1->cmdname));
strcpy(f1[0].cmd[0].cmdname,"command1");
printf("name is %s\n",f1[0].cmd[0].cmdname);
strcpy(f1[0].cmd[1].cmdname,"command2");
printf("name is %s\n",f1[0].cmd[1].cmdname);
strcpy(f1[0].cmd[2].cmdname,"command3");
printf("name is %s\n",f1[0].cmd[2].cmdname);
strcpy(f1[0].cmd[2].args[0].argname,"argument1");
printf("name is %s\n",f1[0].cmd[2].args[0].argname);
strcpy(f1[0].cmd[2].args[0].argname,"argument1");
printf("name is %s\n",f1[0].cmd[2].args[1].argname);
(f1[0].cmd[0].args[0]).argname = malloc(20*sizeof(char*));
strcpy((f1[0].cmd[0].args[0]).argname,"argument1");
printf("name is %s\n",(f1[0].cmd[0].args[0]).argname);
*/
}

Related

BUG: Unable to handle kernel paging request at error for the sample kernel module

I am writing a sample kernel module which reads data sent through ioctl call from application and prints them.
I am passing structure "ioctl_struct" through ioctl from the application and in the kernel module, I will be printing its member variables.
this works absolutely fine in a few machines. In a few machines
"BUG: unable to handle kernel paging request at"
the error is thrown while accessing "name and testStruct's id1 and id2".
I don't think this module is hardware/kernel dependent.
I am not sure where it's going wrong. any help would be appreciated.
thanks.
Driver.c kernel module
static const char DEVICE_NAME[]="testipc";
static struct proc_dir_entry * proc_ipc = NULL;
struct test
{
int id1;
int id2;
};
struct ioctl_struct
{
__user struct test *testStruct;
__user int * id;
__user char * name;
int cmd;
};
static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);
static long etx_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static struct file_operations fops =
{
.owner = THIS_MODULE,
.read = etx_read,
.write = etx_write,
.open = etx_open,
.unlocked_ioctl = etx_ioctl,
.release = etx_release,
.unlocked_ioctl = etx_ioctl,
};
static long etx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
printk("reached ioctl....\n");
struct ioctl_struct buf;
if (copy_from_user(&buf, (void *)arg, sizeof(buf)))
return -EFAULT;
printk("succes..2\n");
printk("id %d\n",buf.id);
printk("cmd %d\n",buf.cmd);
printk("filename %s\n",buf.name);
printk("token %d\n",buf.testStruct->id1);
printk("token %d\n",buf.testStruct->id2);
return 0;
}
static int __init etx_driver_init(void)
{
printk("new test driver loaded..");
proc_ipc = proc_create(DEVICE_NAME, 0, NULL, &fops);
if (!proc_ipc)
{
printk(KERN_ALERT "Unable to create /proc/%s\n", DEVICE_NAME);
return 1;
}
return 0;
}
void __exit etx_driver_exit(void)
{
if (proc_ipc)
proc_remove(proc_ipc);
proc_ipc = NULL;
}
module_init(etx_driver_init);
module_exit(etx_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lin");
MODULE_DESCRIPTION("A simple driver");
MODULE_VERSION("1.0");
and following is my application file
#include <stdio.h>
#include<sys/ioctl.h>
# define __user
static int fd=NULL;
#define TEST_IOCTL _IOWR('z', 80, struct ioctl_struct)
struct test
{
int id1;
int id2;
};
struct ioctl_struct
{
__user struct test *testStruct;
__user int * id;
__user char * name;
int cmd;
};
void init()
{
printf("\nOpening Driver\n");
fd = open("/proc/testipc", O_RDWR);
if(fd < 0) {
printf("Cannot open device file...\n");
return 0;
}
}
void send()
{
int id=5;
int *pid=id;
char name[10]={'H','e','l','l','o'};
struct test testStruct;
testStruct.id1=44;
testStruct.id2=33;
struct ioctl_struct request;
request.name = name ;
request.id = pid;
request.cmd = 33;
request.testStruct = &testStruct;
ioctl(fd, TEST_IOCTL, &request);
}
void finish()
{
printf("Closing Driver\n");
close(fd);
}
int main()
{
init();
send();
finish();
return 0;
}
In dmesg,
id 5,
cmd 33,
Hello,
44,
33,
should be printed

Convert "Tcl_Obj* const objv[]" to "char** argv"

I'm using Tcl 8.6 and I'm trying to do something like this to add functions to the tcl interpreter
Tcl_Interp* interp,
void init() {
interp = Tcl_CreateInterp();
}
void add_tcl_function(char* cmd, function<int(int,char**)> F) {
obj2argv* o2a = new obj2argv;
auto lambda_proc = [&](
ClientData cdata,
Tcl_Interp* interp,
int objc,
Tcl_Obj* const objv[])
{
o2a->set(objc, objv);
F(objc, o2a->get_argv());
};
auto lamba_delete = [&](
delete o2a;
};
Tcl_CreateObjCommand(interp, cmd, lamda_proc, NULL, lamda_delete);
}
What I'm wondering is how to convert "Tcl_Obj* const objv[]" to "char** argv"?
I was thinking about creating a class:
class obj2argv {
obj2argv();
void set(int objc, Tcl_Obj* const objv[]);
char** get_argv();
private:
//...
};
any ideas on how to implement set() and get_argv()?
Is there an easier way to do this?
Thanks.
obj2argv* o2a = new obj2argv;
If you're interfacing a function that's fundamentally working with const char** for arguments, you should register the function with Tcl_CreateCommand and let Tcl handle the mapping to strings for you. It already has all the mechanisms required.
More formally, you are dealing with a gluing function with this signature:
typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
int argc, CONST84 char *argv[]);
The CONST84 should be read as being plain const in all new code, and ClientData is a pointer-sized value that Tcl just hands around and never inspects (same as with your existing code).
If you are going to do the mapping yourself, Tcl_GetString takes a Tcl_Obj* and returns the char* representation of it. The representation should be usually treated as const; it simply isn't formally typed as such for historical reasons.
I wanted to add some more information:
I gave up on using lambda's because when I added capture list it won't convert the lambda to a function pointer for some reason. So I went with the traditional approach (see below). EXCEPT: I still have not idea why the TCL document says
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
const char *argv[]);
But the compiler requires this to compile:
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
Tcl_Obj* const* argv);
The Code:
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* argv)
{
function<int(int,char**)> F = *(function<int(int,char**)>*)clientData;
return F(argc, (char**) argv); // <= CAST DOESN'T SEEM RIGHT
}
void cmd_delete(ClientData clientData)
{
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)&F, cmd_delete);
}
VERSION 2:
struct cmd_data {
//Tcl_Interp* interp,
function<int(int,char**)> F;
int argc;
char* argv[MAX_ARGS];
};
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* objv)
{
auto cmd_data1 = (struct cmd_data*) clientData;
cmd_data1->argc = argc;
for(int i=0; ((i < argc) && (i < MAX_ARGS)); i++) {
cmd_data1->argv[i] = Tcl_GetString(objv[i]);
// Who owns object returned by Tcl_GetString?
// memory leak? or invalid after return from function?
// garbage collected by tcl interp?
}
return cmd_data1->F(argc, cmd_data1->argv);
}
void cmd_delete(ClientData clientData)
{
auto cmd_data1 = (struct cmd_data*) clientData;
if (cmd_data1) {
delete cmd_data1;
}
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
auto cmd_data1 = new struct cmd_data;
cmd_data1->F = F;
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)cmd_data1, cmd_delete);
}
void init_tcl_commands() {
auto lambda_hello = [&](int argc ,char** argv) -> int {
cout << "HELLO WORLD!\n";
return 0;
};
tcl_backend::add_tcl_function("hello", lambda_hello);
}

GCC 5 error, maybe used uninitialized

How do I initialize ua in this struct?
static int clk_init_vdd_class(struct device *dev, struct clk *clk, int num,
unsigned long *fmax, int *uv, int *ua)
Here is is rest of code, krait-8974.c
Found answer,
Line # 683
Edited by adding
int *uv = 0, *ua = 0;
Here is full code
static int
clock_krait_8974_driver_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct clk *c;
int speed, pvs, pvs_ver, config_ver, rows, cpu;
unsigned long *freq, cur_rate, aux_rate;
int *uv = 0, *ua = 0;
u32 *dscr = NULL, vco_mask, config_val;
int ret;
vdd_l2.regulator[0] = devm_regulator_get(dev, "l2-dig");
if (IS_ERR(vdd_l2.regulator[0])) {
dev_err(dev, "Unable to get l2-dig regulator!\n");
return PTR_ERR(vdd_l2.regulator[0]);
}

How do I do something like a memcpy in D

I have a memory location a and I want to copy a certain amount of bytes to another location fast, how would I do this in D ?
For example how would i do this:
int main()
{
void* src_data = 0x40001255;
void* dst_data = 0x47F22000;
u32 size = 0x200;
memcpy(dst_data, src_data, size);
}
Also how would fill a struct fast:
struct data_struct
{
u32 block1;
u32 block2;
u32 block3;
u32 block4;
u32 block5;
u62 block6;
u128 bigblock;
} data_struct_t;
int main()
{
void* src_data = 0x40001255;
struct data_struct_t dst_data;
u32 size = sizeof(data_struct);
memcpy(dst_data, src_data, size);
}
Thanks!
Roel
Assigning to a slice will perform an array copy, which calls memcpy internally.
void main()
{
void* src_data = 0x40001255;
void* dst_data = 0x47F22000;
uint size = 0x200;
dst_data[0..size] = src_data[0..size];
}
For the second one:
struct data_struct
{
uint block1, block2, block3, block4, block5;
ulong block6;
uint[4] bigblock;
}
void main()
{
auto src_data = cast(data_struct*) 0x40001255; // unaligned, WTF?!
auto dst_data = *src_data;
}
Note that you also have access to C's memcpy in D. D can directly access C's whole standard library.

Is it possible to "embed" a structure of variable type into another structure? (GCC)

Is it possible to embed a structure of varying type inside another structure in C?
Basically I want to do something like this.
struct A { int n; void *config; }
struct AConfig { int a; char *b; }
struct BConfig { int a; float b; }
const struct A table[] = {
{ 103, (void*)(struct AConfig){ 1932, "hello" } },
{ 438, (void*)(struct BConfig){ 14829, 33.4f } }
}
Is this possible in C or do I have to define the structures separately?
No, it doesn't work like that. You need explicit storage for each structure:
struct A { int n; void *config; };
struct AConfig { int a; char *b; };
struct BConfig { int a; float b; };
struct AConfig ac = { 1932, "hello" };
struct BConfig bc = { 14829, 33.4f };
const struct A table[] = {
{ 103, &ac },
{ 438, &bc }
};
Edit:
Another possibility is to utilize a union and C99 (-std=c99) named initializers:
enum config_type { CT_INT, CT_FLOAT, CT_STRING };
union config_value {
int int_value;
float float_value;
const char* string_value;
};
struct config {
enum config_type ctype;
union config_value cvalue;
};
struct config sys_config[] = {
{ CT_INT, { .int_value = 12 }},
{ CT_FLOAT, { .float_value = 3.14f }},
{ CT_STRING, { .string_value = "humppa" }}};
void print_config( const struct config* cfg ) {
switch ( cfg->ctype ) {
case CT_INT:
printf( "%d\n", cfg->cvalue.int_value ); break;
case CT_FLOAT:
printf( "%f\n", cfg->cvalue.float_value ); break;
case CT_STRING:
printf( "%s\n", cfg->cvalue.string_value ); break;
default:
printf( "unknown config type\n" );
}
}
You can use a union:
struct AConfig { int a; char *b; };
struct BConfig { int a; float b; };
struct A {
int n;
union {
struct AConfig a;
struct BConfig b;
};
};
Note that a and b are in the exact same space in memory. So if you are going to use the A.a you should not use A.b and vice versa.
Since this is an anonymous union, you can reference both a and b as if they were direct fields of struct A:
struct A sa;
sa.n = 3;
sa.b.a = 4;
sa.b.b = 3.14;
It would work if BConfig had a float pointer to b.
By the way, maybe you need to refactor your code to fit to C syntax.
#include <stdio.h>
#include <stdlib.h>
typedef struct { int n; void *config; } Config;
typedef struct { int a; char *b; } AConfig;
typedef struct { int a; float *b; } BConfig;
int main(void) {
AConfig A;
BConfig B;
A.a= 103;
A.b= "hello";
B.a= 438;
B.b=(float *) malloc (sizeof(float));
*(B.b)= 33.4f;
const Config table[] = {
{ A.a, (void *) A.b },
{ B.a, (void *) B.b }
};
printf("Hi\n");
return 0;
}
You may prefer a union. My union syntax is a little rusty, but something like this:
union config { char* c; float d; };
struct A {int n; int a; union config b;};
const struct A table[] = {
{103, 1932, { .c = "hello" } },
{14829, 438, { .d = 33.4f } }
};
You need C99 for the designated initalizer (the .c or .d in the table), and obviously some way to tell if you're accessing a char* or a float, but I assume you have that covered somewhere else.

Resources