繁体   English   中英

在c中使用openmp在并行循环中分配和释放数组

[英]allocate and free array in parallel loop with openmp in c

我有并行循环,我将内存分配为数组并在最后释放该数组。

问题是,当我想释放它时,由于并行性,不清楚我应该释放哪个数组,它是在并行循环中创建的,我找不到当前数组大小。

这是我的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>

/* PRIVATE FUNCTIONS */

static int split(char* input, char* delim, char** result,int array_idx);
/*******************************************************************************
***        FUNCTIONS DEFINITIONS
*******************************************************************************/
int parser(){

    
    int ids_size=3;
    long int_comma_size_arr[]={3,2,4};
    char* str_arr[]={"one,two,three","for,five","six,seven,eight,nine"};
    char* delim=",";
    

    #pragma omp parallel for 
    for(int i=0; i <ids_size; i++) {

        
        char* keys[int_comma_size_arr[i]];
        split(str_arr[i], delim, keys, 0 );

        #pragma omp parallel for 
        for (int n=0; n<int_comma_size_arr[i]; n++) {
            printf(keys[n]);
        }
        

        for (int m=0;m <int_comma_size_arr[i];m++){
            free(keys[m]);
        }
    }
}

/*******************************************************************************
***        PRIVATE FUNCTIONS
*******************************************************************************/
/* 
function name: split
stores array of strings which are chunks of input string, splited with delimiter.
*/
int split(char* input, char* delim, char** result,int array_idx) {
   
    char* found= strstr(input, delim);

    if (found==""||strlen(input)==0){
 
        return 0;

    }else if(found == NULL){
    
        result[array_idx]=malloc(strlen(input)+1 * sizeof(char));
        strncpy(result[array_idx], input, strlen(input));
        *(result[array_idx] + strlen(input)) = '\0';
        return 0;

    }else{

        int length = found - input;
        result[array_idx]=malloc((length+1) * sizeof(char));
        strncpy(result[array_idx], input, length);
        *(result[array_idx] + length) = '\0';
        return split(found+strlen(delim),delim,result,array_idx+1); 
    }
}

如您所见,当我尝试释放例如在 i=0 处创建的密钥时,在循环中,int_key_size_arr[i] 的指针指向 int_key_size_arr[1]。

我试图用下一个 2 个选项替换 second for 来解决这个问题,但是我得到了分段错误错误。

  • ‍‍for (int m=0;m <sizeof(keys)/sizeof(*keys);m++)
  • for (int m=0;m <sizeof(keys)/sizeof(keys[0]);m++)

由于我的键大小可能很大,我不想在最后释放所有键数组。

那么我该如何解决分段错误的问题。

如果我将您的parser()函数重命名为main() ,生成的程序对我来说运行良好,并且 Valgrind 不会检测到任何不正确的内存访问或释放。

由于您询问如何知道要释放多少拆分块,因此我假设您的目标是消除代码对int_comma_size_arr数组的依赖,该数组给出了每个输入的预期块数。

修改split()函数以返回分配的块总数很容易,如果您继续将块指针存储在数组中,这将是一个可行的解决方案。 但是,您使用int_comma_size_arr不仅要知道要释放多少块,还要提前知道要为块指针提供多少存储空间。 您还需要删除后一个依赖项。

可能的解决方案包括:

  • 在实际执行拆分之前计算分隔符的出现次数,然后使用它来确定要提供和释放多少块。

  • 使用输入数组的长度作为将找到的块数量的上限,并为那么多块分配足够的空间(其中一些在大多数情况下将不使用)

  • 随时为块数组动态分配和重新分配空间,以适应实际找到的块数量

  • 使用链表或类似的数据结构来返回块,而不是数组(这也提供了另一种方法来知道要释放多少块)


此外,

  • 请注意,您的found==""条件将始终评估为 0 ( false ),原因有两个:

    1. 比较测试found中存储的地址是否与""的地址相同,在这种情况下,这些地址永远不可能相等。

    2. strstr()将返回指向分隔符外观的指针或空指针。 因此,即使==正在执行内容比较 ala strcmp() ,除非分隔符为空(实际上,您的代码不支持),否则内容永远不会匹配。

  • 您的split()函数复制了strdup()strndup()的行为。 如果您可以使用其中的一个或两个,那么使用它们将使split()更加清晰和清晰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM