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

C语言OpenMP环境下结构体数组创建销毁的内存问题排查

OpenMP并行段错误排查与测试代码验证

问题背景与现象

我在C代码的串行部分动态分配了结构体CONF的二维数组:

CONF **conf = (CONF **) malloc (Nc*sizeof(CONF *)); 

Nc为运行时获取的变量,每个conf[i]的大小存储在long int数组Nc_size中,随后逐个分配conf[i]:

for (i=0; i<Nc; i++) {
    long int sz;
    // 除最后一个外的所有元素                                         
    if (i+1!=Nc) {
        sz = MC;
    }
    // 最后一个元素                                                 
    else {
        sz = conflistd%MC;
    }
    Nc_size[i] = sz;
    (conf)[i] = (CONF *) malloc(sz*sizeof(CONF));
}

CONF是包含动态double数组的复杂结构体,填充完成后,我尝试通过OpenMP并行调用CLUSTERINGL函数修改每个conf[i]:

#pragma omp parallel private(i, NIR) shared(conf, Nc_size)
{
    #pragma omp for
    for (i=0; i<Nc; i++) {
        conf[i] = CLUSTERINGL (conf[i], &sz, ...);
    }
}

CLUSTERINGL函数会创建更小的CONF结构体数组,填充原数组的子集后返回,同时释放原conf[i]及其内部资源:

CONF *CLUSTERINGL(CONF *conflist1, long int *conflist1d, ...) {

    CONF *conflist3 = malloc(1 * sizeof(CONF));

    for (j = 0; j < k; j++) {
        if (arrayofconf[j][0] > -1) {
            long int NFR = conflist1[j].NFR;
            i = arrayofconf[j][0];
            // 若为最接近质心的元素
            conflist3 =
                (CONF *)realloc(conflist3, (conflist3d + 1) * sizeof(CONF));
            conflist3[conflist3d].IR = malloc(NIR * sizeof(double));
            conflist3[conflist3d].angles = malloc(NBONDS * sizeof(double));
            conflist3[conflist3d].TR = malloc(3 * (NFR + 1) * sizeof(double));
            conflist3[conflist3d].ROT = malloc(3 * (NFR + 1) * sizeof(double));

            conflist3d++;
        }
    }

    // ... 省略中间业务逻辑

    for (i = 0; i < *conflist1d; i++) {
        if (NIR != 0) {
            free(conflist1[i].IR);
        }
        free(conflist1[i].angles);
        free(conflist1[i].TR);
        free(conflist1[i].ROT);
    }

    free(conflist1);

    *conflist1d = conflist3d;
    return conflist3;
}

串行运行时一切正常,但并行模式下几乎每次都会出现段错误。我猜测可能是向CLUSTERINGL传递conf[i]时需要加&符号,特寻求排查建议。

简化测试代码验证请求

我编写了简化的测试代码,编译命令为gcc main.c -fopenmp -lm,执行命令./a.out 10000000,运行稳定,请求确认该测试代码的概念正确性:

maintypes.h

#include <inttypes.h>

typedef struct {
  long int N;
  double *IR;
} CONF;

main.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include "maintypes.h"
#include <string.h>
#include <ctype.h>
#include <omp.h>
#include <time.h>

CONF *CLUSTERINGL (CONF *conf1, long int *conf1d, long int NIR);


int main (int argc, char *argv[]) {

// 检查是否传入参数
if (argc < 2) {
        printf ("%s","Please, give the number NA\n");
        exit(0);
}

long int conflistd = atoi(argv[1]);
long int MC = 100;
long int NIR = 30;
long int Nc = conflistd/MC + 1;
long int Nc_size[Nc];
//

CONF **conf = (CONF **) malloc (Nc*sizeof(CONF *));

// 循环变量

long int i=0, j=0;
long int count=0;

for (i=0; i<Nc; i++) {
  long int sz;
  // 除最后一个外的所有元素
  if (i+1!=Nc) {
    sz = MC;
  }
  // 最后一个元素
  else {
    sz = conflistd%MC;
  }
  Nc_size[i] = sz;                      
  (conf)[i] = (CONF *) malloc(sz*sizeof(CONF));
  for (j=0;j<sz;j++) {
    conf[i][j].N = count;
    conf[i][j].IR = malloc(NIR*sizeof(double));
    for (long int m=0;m<NIR;m++) {
      conf[i][j].IR[m] = 1.33*m;
    }
    count = count + 1;   
  }

}

printf ("Starting parallel\n");
#pragma omp parallel private(i) shared (conf, Nc_size, Nc, NIR) default(none)
{
#pragma omp for
for (i=0;i<Nc;i++) {
  long int sz = Nc_size[i];
  if (sz>4) {
    conf[i] = CLUSTERINGL(conf[i], &sz, NIR);
    Nc_size[i] = sz;
  }
}

}

return 0;
}


CONF *CLUSTERINGL (CONF *conf1, long int *conf1d, long int NIR) {

long int d = *conf1d/3;
CONF *confnew = (CONF *) malloc (d*sizeof(CONF));

long int j=0;

for (j=0;j<d;j++) {
  confnew[j].N = conf1[j].N;
  confnew[j].IR = malloc(NIR*sizeof(double));
  for (long int m=0;m<NIR;m++) {
    confnew[j].IR[m] = pow(sqrt(conf1[j].IR[m])*5*j,1.8);
    confnew[j].IR[m]*5;
    confnew[j].IR[m]*confnew[j].IR[m];
  }
}


// 清理资源

for (j=0;j<*conf1d;j++) {
  free (conf1[j].IR);
}

free (conf1);

*conf1d=d;

return confnew;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:25:55