[英]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 来解决这个问题,但是我得到了分段错误错误。
由于我的键大小可能很大,我不想在最后释放所有键数组。
那么我该如何解决分段错误的问题。
如果我将您的parser()
函数重命名为main()
,生成的程序对我来说运行良好,并且 Valgrind 不会检测到任何不正确的内存访问或释放。
由于您询问如何知道要释放多少拆分块,因此我假设您的目标是消除代码对int_comma_size_arr
数组的依赖,该数组给出了每个输入的预期块数。
修改split()
函数以返回分配的块总数很容易,如果您继续将块指针存储在数组中,这将是一个可行的解决方案。 但是,您使用int_comma_size_arr
不仅要知道要释放多少块,还要提前知道要为块指针提供多少存储空间。 您还需要删除后一个依赖项。
可能的解决方案包括:
在实际执行拆分之前计算分隔符的出现次数,然后使用它来确定要提供和释放多少块。
使用输入数组的长度作为将找到的块数量的上限,并为那么多块分配足够的空间(其中一些在大多数情况下将不使用)
随时为块数组动态分配和重新分配空间,以适应实际找到的块数量
使用链表或类似的数据结构来返回块,而不是数组(这也提供了另一种方法来知道要释放多少块)
此外,
请注意,您的found==""
条件将始终评估为 0 ( false
),原因有两个:
比较测试found
中存储的地址是否与""
的地址相同,在这种情况下,这些地址永远不可能相等。
strstr()
将返回指向分隔符外观的指针或空指针。 因此,即使==
正在执行内容比较 ala strcmp()
,除非分隔符为空(实际上,您的代码不支持),否则内容永远不会匹配。
您的split()
函数复制了strdup()
和strndup()
的行为。 如果您可以使用其中的一个或两个,那么使用它们将使split()
更加清晰和清晰。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.