c: using strcpy() on an element inside a data structure - struct

i am currently learning cs50. i am currently studying data structures..i came across a problem...please see if you could help:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node{
char *name;
int age;
};
typedef struct node node;
int main(){
node *p=malloc(sizeof(node));
if (p==NULL){
return 1;
}
p->name="hussein";
p->age=32;
printf("staff1: %s, %d\n", p->name, p->age); //why doesn't this line of code work? program crashes here
strcpy(p->name, "hasan");
printf("staff1: %s, %d\n", p->name, p->age);
free(p);
return 0;
}

Use p->name = "hasan"; instead of strcpy(p->name, "hasan");.
The name in struct node is a pointer which can point to an array of char.
It didn't have allocated memory space for the char array.

Related

Shared Memory giving ambiguous results

I was trying to communicate between two processes using Shared Memory concept. But here, though I have pointed the shared memory addresses of different variables to different files, they seem to be connected. As soon as I alter value of one variable, the new value overwrites on other variable too, in this case, se1->val and se2->val are coming out to be connected. Can someone help why it's happening so?
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define s(t) scanf("%d",&t)
#define p(t) printf("%d ",t)
struct sem
{
int val;
int xy;
};
struct sem* se1;
struct sem* se2;
int main()
{
printf("You in P1\n");
key_t key1,key2;
key1=ftok("shmfile1",0);
key2=ftok("shmfile3",0);
int shmid1=shmget(key1, sizeof(struct sem),0644|IPC_CREAT);
int shmid2=shmget(key2, sizeof(struct sem),0644|IPC_CREAT);
se1=shmat(shmid1,NULL,0);
se2=shmat(shmid2,NULL,0);
se1->xy=4;
se2->xy=8;
se1->val=0;
se2->val=1;
int r=10;
while(r--)
{
printf("\nIn P1 process ");
while(se2->val==0);
se2->val--;
se1->xy=se2->xy+1;
se1->val++;
p(se1->xy);
p(se2->xy);
}
return 0;
}
It is expected se1->val and se2->val will lead to semaphore type results, but due to overwriting it's not happening!

Malloc function shows error

`struct node * createLL(struct node *head)
{
int num;
struct node *new_node;
printf("enter the numbers you want to insert:\n");
printf("enter -1 to quit");
scanf("%d",&num);
while(num!=-1)
{
new_node=(struct node *) malloc (sizeof(struct node *));
new_node->data=num;
if(head==NULL)
{
new_node->next=NULL;
head=new_node;
}
else
{
new_node->next=head;
head=new_node;
}
printf("enter the numbers you want to insert:\n");
printf("enter -1 to quit");
scanf("%d",&num);
}
return head;
}`
the malloc used to create a new_node for the linked list of type struct node* is showing error. it says "malloc is not declared within scope"..
i referred books too..the code is same.. couldnot figure out how the error
can be corrected.
Are you sure you included the correct library in the header? Make sure you included
#include <stdlib.h>

cudaMemcpyAsync only one member of a struct from device to host

I have a struct with multiple members and I want to do some operations on parts of the member by GPUs. To make the size of communication as small as possible, I hope to copy back only those members which have been modified. Can cuda do that?
struct nodeInfo;
typedef struct nodeInfo
{
int x;
int y;
}nodeProp;
int main(int argc, char* argv[]){
int ngpus;
CHECK(cudaGetDeviceCount(&ngpus));
cudaStream_t stream[ngpus];
nodeProp *Nodes;
nodeProp *gpuNodes[ngpus];
int rankSize = 10;
int deviceSize = rankSize/ngpus;
CHECK(cudaMallocHost((void**)&Nodes,rankSize*sizeof(nodeProp)));
for(int i = 0; i < ngpus; i++)
{
cudaSetDevice(i);
cudaStreamCreate(&stream[i]);
CHECK(cudaMalloc((void**)&gpuNodes[i],deviceSize*sizeof(nodeProp)));
CHECK(cudaMemcpyAsync(gpuNodes[i],Nodes+i*deviceSize,deviceSize*sizeof(nodeProp),cudaMemcpyHostToDevice,stream[i]));
}
for(int i = 0; i < ngpus; i++)
{
cudaSetDevice(i);
kernel_x_Operation<<<grid_size,block_size,0,stream[i]>>>(gpuNodes[i]);//Some operation on gpuNodes.x
//How to write the memcpy function? Can I just copy one member of the struct back?
CHECK((void*)cudaMemcpyAsync((Nodes+i*deviceSize)->x, gpuNodes[i]->x), sizeof(int)*deviceSize,cudaMemcpyDeviceToHost,stream[i]));
cudaDeviceSynchronize();
}
}
No, you can't do that. But you can achieve something similar by laying your data out as a Struct of Arrays instead of an Array of Structs.
Have a look at Structure of Arrays vs Array of Structures in cuda to see how this might even improve performance.

How to print n number of string in c?

#include<stdio.h>
#include<string.h>
#include<malloc.h>
int main()
{
char *name;
int a;
name=(char *)malloc(sizeof(name));
printf("no. of names:");
scanf("%d",&a);
int i;
for(i=0;i<a;i++)
{
printf("enter the names:");
scanf("%s",name);
}
for(i=0;i<a;i++)
{
printf("entered names are:%s\n",name);
}
return 0;
free(name);
}
how to print n numbers of entered string in c am already asked this question but i dont got any proper answer any body known the answer please edit my code please if you run my code its displays last string only i dont know why please help..
You need an array of names. To achieve what you are trying to do you can use either a static array with the maximum size or allocate the memory dinamically as in the following program.
Note that you should also test the return value of malloc... just in case.
#include<stdio.h>
#include<string.h>
#include<malloc.h>
int main()
{
char **name;
int a;
printf("no. of names:");
scanf("%d",&a);
int i;
if( a<=0 )
return 0;
name = (char**)malloc( sizeof(char*)*a);
for(i=0;i<a;i++)
{
printf("enter the name:");
name[i]=(char*)malloc( sizeof(char)*128);
scanf("%s",name[i]);
}
for(i=0;i<a;i++)
{
printf("entered names are:%s\n",name[i]);
free(name[i]);
}
free(name);
return(0);
}
Note I had to cast malloc because the compiler that the OP is using raise the error " cannot convert from 'void ' to 'char ** ' " (which means that it's old enough..)
In
name=(char *)malloc(sizeof(name));
name is a char*, so sizeof(name) is the size of an address. Hence you are not allocating enough memory.
Just allocate more memory:
name=(char *)malloc(sizeof(char)*20); //allocating 20 bytes for the block that name will point tor
In addition to wrong space allocation (answered by brokenfoot), you will not get the results you want because you are reading all the names over and over in the same variable name, and later printing the name input last a times:
for(i=0;i<a;i++)
{
printf("enter the names:");
scanf("%s",name);
}
for(i=0;i<a;i++)
{
printf("entered names are:%s\n",name);
}
The right approach would be to use an array to store all the names, and later print them one by one. For example:
for(i=0;i<a;i++)
{
printf("Enter the names:")
scanf("%s",name[a]);
}
print("The entered names are: ");
for(i=0;i<a;i++)
{
printf("%s", name[a]);
}

IOCTL Method - Linux

I have an exam question and I can't quite see how to solve it.
A driver that needs the ioctl method to be implemented and tested.
I have to write the ioctl() method, the associated test program as well as the common IOCTL definitions.
The ioctl() method should only handle one command. In this command, I need to transmit a data structure from user space to kernel space.
Below is the structure shown:
struct data
{
     char label [10];
     int value;
}
The driver must print the IOCTL command data, using printk();
Device name is "/dev/mydevice"
The test program must validate driver mode using an initialized data structure.
Hope there are some that can help
thanks in advance
My suggestion:
static int f_on_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
int ret;
switch (cmd)
{
case PASS_STRUCT:
struct data pass_data;
ret = copy_from_user(&pass_data, arg, sizeof(*pass_data));
if(ret < 0)
{
printk("PASS_STRUCT\n");
return -1;
}
printk(KERN ALERT "Message PASS_STRUCT : %d and %c\n",pass_data.value, pass_data.label);
break;
default:
return ENOTTY;
}
return 0;
}
Definitions:
Common.h
#define SYSLED_IOC_MAGIC 'k'
#define PASS_STRUCT _IOW(SYSLED_IOC_MAGIC, 1, struct data)
The test program:
int main()
{
int fd = open("/dev/mydevice", O_RDWR);
data data_pass;
data_pass.value = 2;
data_pass.label = "hej";
ioctl(fd, PASS_STRUCT, &data_pass);
close(fd);
return 0;
}
Is this completely wrong??

Resources