You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中malloc与共享内存结合使用的异常问题排查

共享内存动态数组与进程异常问题

问题描述

尝试将shared_pid_data结构体存入共享内存,因需要动态存储PID数组使用了malloc(也曾尝试calloc,结果一致),但出现以下异常:

  • 初始化阶段,共享内存中本该为0的字段输出类似内存地址的乱值;
  • 调用读取共享内存的print_statistics()函数时输出数据异常;
  • 原本可正常存储int变量的init_ipc()函数,复制适配为分配pid_t指针的逻辑后,shared_data_t结构体返回null;
  • 循环创建5个进程时,有2-3个进程创建失败。
    修改atomSharedPidInit函数后问题依旧。

相关代码

完整源代码

#include "ipc.h"
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <fcntl.h>     // O_CREAT, O_RDWR
#include <sys/mman.h>  // shm_open, mmap, PROT_READ, PROT_WRITE, MAP_SHARED
#include <sys/stat.h>  // S_IRUSR, S_IWUSR
#include <unistd.h>    // ftruncate, pid_t
#include <sys/types.h> // pid_t
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int energy_produced;
    int active_atoms;
    int waste;
    int activation_flag;
    int total_energy;
    int energy_consumed;
    int scissions;
    int activations;
    int energy_demand;
    int sim_duration;
    int energy_explode_threshold;
    int n_atomi_init;
    int min_n_atomico;
    int n_nuovi_atomi;
    int max_num_atomico;
    int min_num_atomico;
} shared_data_t;

typedef struct{
    pid_t master;
    pid_t alimentatore;
    pid_t attivatore;
    pid_t *atomi_pid;
    int dimensione;
} shared_pid_data;

static int shmidA;
static int semidA;

void init_ipc() {
    key_t key = ftok("shmfileI",65);
    shmid = shmget(key, sizeof(shared_data_t), 0666|IPC_CREAT);
    shared_data = (shared_data_t*) shmat(shmid, (void*)0, 0);
    key_t sem_key = ftok("semfileI", 75);
    semid = semget(sem_key, 1, 0666 | IPC_CREAT);
    semctl(semid, 0, SETVAL, 1);
}

void lockA() {
    struct sembuf sb = {(unsigned short) 0, -1, 0};
    semop(semidA, &sb, 1);
}

void unlockA() {
    struct sembuf sb = {(unsigned short) 0, 1, 0};
    semop(semidA, &sb, 1);
}

void atomSharedPidInit() {
    key_t key = ftok("Ashmfile",65);
    shmidA = shmget(key, sizeof(shared_pid_data), 0666|IPC_CREAT);
    shared_pid_atom = (shared_pid_data*) shmat(shmidA, (void*)0, 0);
    shared_pid_atom->atomi_pid = (pid_t*)malloc(sizeof(pid_t) * 10); // Initial capacity of 10 PIDs
    shared_pid_atom->dimensione = 0;
    key_t sem_key = ftok("Asemfile", 75);
    semidA = semget(sem_key, 1, 0666 | IPC_CREAT);
    semctl(semidA, 0, SETVAL, 1);
}

void atomSharedPidWrite(pid_t pid) {
    lockA();
    if (shared_pid_atom->dimensione % 10 == 0) {
        shared_pid_atom->atomi_pid = (pid_t*)realloc(shared_pid_atom->atomi_pid, sizeof(int) * ((size_t)shared_pid_atom->dimensione + 10));
    }
    shared_pid_atom->atomi_pid[shared_pid_atom->dimensione] = pid;
    shared_pid_atom->dimensione++;
    unlockA();
}

void print_statistics() {
    printf("Current state:\n");
    printf("Total energy: %d\n", get_total_energy());
    printf("Total energy consumed: %d\n", get_energy_consumed());
    printf("Total energy available: %d\n", get_energy_produced()); 
    printf("Total atomi attivi: %d\n", get_active_atoms());
    printf("Total scissions: %d\n", get_scissions());
    printf("Total activations: %d\n", get_activations());
    printf("Total scorie: %d\n", get_waste());
    printf("+---------------------------------------------------+\n");
}

int main(int argc, char *argv[]) {
    init_ipc();
    print_statistics();
    atomSharedPidInit();
    print_statistics();

    for (int i = 0; i < 5; i++) {
        atomoPID = fork();
        if (atomoPID == 0) {
            srand((unsigned int)(time(NULL) + getpid()));
            printf("wirite pid Shared data\n");
            atomSharedPidWrite(getpid());
            int numero_atomico = rand() % max_num_atomico + min_num_atomico;
            printf("%d %d %d ", numero_atomico, max_num_atomico, min_num_atomico);
            char num_atomico_str[10];
            sprintf(num_atomico_str, "%d", numero_atomico);
            execl("./a", "./a", num_atomico_str, NULL);
            exit(0);
        } else if (atomoPID < -1) {
            kill(getpid(), SIGINT);
            exit(EXIT_FAILURE);
        }
    }

    while(1){
        print_statistics();
        sleep(1);
    }

    return EXIT_SUCCESS;

}

修改后的atomSharedPidInit函数

void atomSharedPidInit() {
    key_t key = ftok("Ashmfile",65);
    shmidA = shmget(key, sizeof(shared_pid_data), 0666|IPC_CREAT);
    shared_pid_atom = (shared_pid_data*) shmat(shmidA, (void*)0, 0);
    shared_pid_atom->atomi_pid = (pid_t*) shmat(shmidA, (void*)0, 0);
    shared_pid_atom->atomi_pid = (pid_t*)malloc(sizeof(pid_t) * 10);
    shared_pid_atom->dimensione = 0;
}

异常输出

首次两次打印结果

+---------------------------------------------------+
Current state:
Total energy: 0
Total energy consumed: 0
Total energy available: 0
Total atomi attivi: 0
Total scissions: 0
Total activations: 0
Total scorie: 0
+---------------------------------------------------+
Current state:
Total energy: -461014896
Total energy consumed: 24901
Total energy available: 0
Total atomi attivi: 0
Total scissions: 0
Total activations: 0
Total scorie: 0
+---------------------------------------------------+

while循环内打印结果

+---------------------------------------------------+
Current state:
Total energy: -1854515536
Total energy consumed: 22593
Total energy available: 5320
Total atomi attivi: 5349
Total scissions: 0
Total activations: 0
Total scorie: 5346
+---------------------------------------------------+
Current state:
Total energy: -1854515536
Total energy consumed: 22613
Total energy available: 5300
Total atomi attivi: 5349
Total scissions: 0
Total activations: 0
Total scorie: 5346
+---------------------------------------------------+

内容的提问来源于stack exchange,提问作者MiusiZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:42:01