gpt4 book ai didi

C 中结构的副本

转载 作者:行者123 更新时间:2023-11-30 14:35:01 25 4
gpt4 key购买 nike

在 c 语言的项目中,我必须从共享内存中复制结构数组

我正在做:

int status = 0;
pid_t wpid;
f1 *input = (f1*) shmat(shmid,0,0);
while ((wpid = wait(&status)) > 0){
memcpy(&carList, &input, sizeof(input));
}

f1是我的汽车结构。

但 carList 中没有复制任何内容,但值是来自子进程的输入我认为问题出在这部分代码上,我尝试了多种其他可能性,但我没有找到其他地方。

我必须使用共享内存创建 20 个儿子,并让它们为像汽车这样的比赛生成随机时间。

因此,我创建了 20 个儿子,将其链接到它们结构数组的条目,并让它们在生成时写入其中。

然后,父亲时不时地复制结构体数组,以制作汽车所有时间的动态表。我知道使用 cpu-scheduler 并不是最好的主意,但这就是我们在讲座中必须做的,所以我们别无选择。

full code but it's a bit long (and i'm french so the notes are in french)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> // bool
#include <unistd.h> //fork
#include <string.h> //strcat
#include <sys/wait.h> //wait
#include <sys/types.h>
#include <sys/shm.h>

#define TURN 3
#define SECTION 3
#define CAR 20
#define KEY 666
#define STANDPOURCENT 10

typedef struct {
int number;
int stands;
bool out;
int totalTime;

int circuit[TURN][SECTION];
} f1;

int carListNumber[CAR] = {7, 99, 5, 16, 8, 20, 4, 55, 10, 26, 44, 77, 11, 18, 23, 33, 3, 27, 63, 88};
f1 carList[CAR];
/***********************************************************************************************************************
* fonctions
**********************************************************************************************************************/

/**
* renvois un nombre compris entre 40 et 45 secondes pour le
* clacul du temps des tours de circuits
* @return integer between 40 and 45
*/
int genSection(){
int time = 45 - (rand() % 9);
sleep(time/20);
return time; // gestion du random et du temps perdu
}

/**
* génération du temps d'arret au stand
* @return integer between 2 and 5
*/
int genRandomStand(){
return 5 - (rand() % 3);
}

/**
* génération nombre entre 1 et 100
* @return int between 1 and 100
*/
int genRandom(){
return 100 - (rand() % 100);
}

/**
* clear de la console
*/
void clrscr(){
system("clear");
}

/**
* affichage du tableau de résultat de tout les tours pour toutes les voitures et sections
*/
void showRun(){
clrscr();
for (int turn = 0; turn < TURN; turn++){
for(int car = 0; car < CAR; car++){
printf("Voiture %3d || turn : %3d ||S1 : %1d | S2 : %2d | S3 : %2d || Total Turn : %3d \n",carList[car].number,
turn+1,
carList[car].circuit[turn][0],
carList[car].circuit[turn][1],
carList[car].circuit[turn][2],
carList[car].circuit[turn][0]+carList[car].circuit[turn][1]+carList[car].circuit[turn][2]);
}
printf("---------------------------------------------------------------------------------------------------------------\n");
}
}

/**
* generation de la liste des structur voitrure sur base de la liste des numero de voitures
* @return void
*/
void init_car_list(int *carListNumber){
for(int i = 0; i < CAR; i++){
carList[i].number = carListNumber[i];
carList[i].stands = 0;
carList[i].out = false;
carList[i].totalTime = 0;
memset(carList[i].circuit, 0, sizeof(carList[i].circuit));
}
}

/**
* initalistation de la voiture passé en param
* @param carNumber
*/
f1 init_car(int carNumber){
f1 tmp;
tmp.number = carNumber;
tmp.stands = 0;
tmp.out = false;
tmp.totalTime = 0;
memset(tmp.circuit, 0, sizeof(tmp.circuit));
return tmp;
}

/**
* fonction du code du fils (voiture)
*/
void circuit_son(int shmid,int carPosition){
int carNumber = carListNumber[carPosition];
//printf("in son %d : car number %d\n",carPosition,carNumber);
f1 *output = (f1 *) shmat(shmid, 0, 0);
printf("Départ de la voiture %d\n",carNumber);
f1 *currentCar;
srand(time()+getpid()); // génération du nouveau random pour chaque fils
//printf("récupération de la strcuct voiture %d \n",carNumber);
for(int i = 0; i < CAR; i++){
if(output[i].number == carNumber){
currentCar = &output[i];
//printf("Récupération de :: output %d || carNumber %d || current car %d \n",output[i].number,carNumber,currentCar->number);
break;
}
}
for(int i = 0; i < TURN; i++){ // pour chaque tour
for(int j = 0; j < SECTION; j++){ // pour chaque section du tour
currentCar->circuit[i][j] = genSection();
printf("car %d , %d \n",currentCar->number,currentCar->circuit[i][j]);
}
if (genRandom() > STANDPOURCENT || (i == (TURN-1) && currentCar->stands == 0)){ // 50% de s'arreter ou si jamais arrêter pendant la course
currentCar->circuit[i][SECTION-1] += genRandomStand();
printf("arret de la voiture %d au stand , temps total de la section 3 : %d \n",currentCar->number,currentCar->circuit[i][SECTION-1]);
currentCar->stands++;
}
}
exit(EXIT_SUCCESS);
}

/**
* fonction du père
* @return
*/
void circuit_father(int shmid){
int status = 0;
pid_t wpid;
// récupération des données de la SM
f1 *input = (f1*) shmat(shmid,0,0);
while ((wpid = wait(&status)) > 0){ // temps que un processus est en cours
memcpy(&carList, &input, sizeof(input));
printf("input %d %d %d \n",input[4].circuit[1][0],input[4].circuit[1][1],input[4].circuit[1][2]);
//showRun();
printf("show run here in father || %d %d %d\n",carList[4].circuit[1][0],carList[4].circuit[1][1],carList[4].circuit[1][2]);
}
}

/**
* gestion des tours d essais des voitures
* @param shmid id de la memoire partagée
* @return -1 if error else 0
*/
int gen_circuit(int shmid) {
for (int car = 0; car < CAR; car++) {
int pid = fork();
if (pid < 0) {
perror("error on creation of car");
printf("\n");
return -1;
}
/* Son */
else if (pid == 0) {
circuit_son(shmid,car);
}
}
/* Parent */
circuit_father(shmid);
return 0;
}

/**
* initalisation de la shared memory
*/
void init_mem(shmid){
f1 *mem = (f1 *) shmat(shmid, 0, 0);
for(int i = 0; i < CAR; i++){
mem[i] = init_car(carListNumber[i]);
}
}

/**
*
* @return
*/
int main(){
// initalisation des voitures
init_car_list(carListNumber);
// allocation de la mem partagée
int shmid = shmget(KEY, (20 * sizeof(f1)),0666 | IPC_CREAT); // 0775 || user = 7 | groupe = 7 | other = 5
if (shmid == -1){
perror("ERROR in creation of the Shared Memory");
printf("\n");
shmctl(shmid,IPC_RMID,NULL); // suppression de la memoire partagée
return 1;
}
init_mem(shmid);
// gestion du circuit

gen_circuit(shmid);
printf("tout les tours sont terminé \n");
printf("affichage des Résultats : \n");
//showRun();

// fin de la course
printf("fin des tours \n");
shmctl(shmid,IPC_RMID,NULL); // suppression de la memoire partagée
return 0; // fin du programme
}

最佳答案

memcpy 有两个主要问题给你打电话,还有一个小问题:

  1. 您通过&input作为源指针。这里的问题是&input是指向变量 input 的指针而不是指向共享内存的指针,其中 input正在指着。这意味着您复制指针而不是所指向的数据。要解决此问题,请使用普通 input .

  2. 根据您使用的尺寸 sizeof(input) ,这是指针本身的大小,而不是它所指向的内容的大小。您可能想要复制的大小是 sizeof carList ,这是目标数组的大小(以字节为单位)。

  3. 小问题是目的地,您在哪里使用 &carList 。这是一个指向数组的指针,类型为 f1 (*)[20] 。您需要的是指向数组第一个元素的指针,即 &carList[0] ,或普通 carList (这是相同的)。

所以调用可能应该是这样的

memcpy(carList, input, sizeof carList);  // Copy from the shared memory into our local array

关于C 中结构的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58731625/

25 4 0
文章推荐: C:查找字符串中的特定字符
文章推荐: c# - .NET 4+ 中 get 存储过程架构的优势?