C 中的分段错误(核心已转储)- 使用 PTHREADS 时
Segmentation fault (core dumped) in C - While Using PTHREADS
大家好,
我的代码有问题,我不知道如何解决(分段错误(核心已转储))!
所以我的老师要我编写一个程序来创建 N 个踏板并让它们做一些事情 calculations.I 有 3 个全局二维数组 A、B、C(我将它们作为指针,因为我不知道大小,用户将其作为参数提供)。我尝试在主函数中为它们分配内存。
所以问题是当我尝试在 "pthread_create(&tid[id],NULL,add,(void *)(long) i);" 中创建踏板时出现分段错误:(。
我不明白为什么 happening.I 尝试使用 gdb 命令,但结果是问题出在 pthread_create.
然而,当我在评论中添加数组(A、B、C)时,他们使用的 malloc 正在运行(但最终结果为 0)。
我正在使用一个虚拟盒子(如果有帮助,里面有 Ubuntu :D)。
以下是我目前写的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
long int p,N,Total_Sum;
long int **A,**B,**C;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t bar;
void * add(void *arg){
long int i,j,Local_Sum=0;
long int lines,start,end,id;
id = (long int)arg;
lines = N/p;
start = id*lines;
end = start+lines;
for(i=start;i<end;i++){
for(j=0;j<N;j++){
A[i][j] = 1;
B[i][j] = 1;
}
}
for(i=start;i<end;i++){
for(j=0;j<N;j++){
C[i][j] = A[i][j] * B[i][j];
Local_Sum += C[i][j];
printf("C[%ld][%ld] = %ld\n",i,j,C[i][j]);
}
}
pthread_mutex_lock(&mutex);
Total_Sum += Local_Sum;
pthread_mutex_unlock(&mutex);
pthread_barrier_wait(&bar);
pthread_exit(0);
}
int main(int argc, char *argv[]){
long int i,j,id;
pthread_t *tid;
if(argc!=3){
printf("Provide Number Of Threads And Size\n");
exit(1);
}
p = atoi(argv[1]);
tid = (pthread_t *) malloc(p*sizeof(pthread_t));
if(tid == NULL){
printf("Could Not Allocate Memory\n");
exit(1);
}
pthread_barrier_init(&bar,NULL,p);
N = atoi(argv[2]);
A = (long int**) malloc(N*sizeof(long int*));
B = (long int**) malloc(N*sizeof(long int*));
C = (long int**) malloc(N*sizeof(long int*));
for(i=0;i<N;i++){
A[i] = (long int*) malloc(N*sizeof(long int));
B[i] = (long int*) malloc(N*sizeof(long int));
C[i] = (long int*) malloc(N*sizeof(long int));
}
if((A==NULL) || (B == NULL) || (C == NULL)){
printf("Count Not Allocate Memory\n");
exit(1);
}
for(i=0;i<p;i++){
pthread_create(&tid[id],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
pthread_join(tid[id],NULL);
}
for(i=0;i<N;i++){
free(A[i]);
free(B[i]);
free(C[i]);
}
free(A);
free(B);
free(C);
printf("Final Result Is Equal To: %ld\n",Total_Sum);
return 0;
}
******我知道由于互斥锁和障碍,它变得有点混乱,但请向我询问进一步的规范:D.******
谢谢!!!!!!
我认为唯一的问题是以下几行中的索引:
for(i=0;i<p;i++){
pthread_create(&tid[id],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
pthread_join(tid[id],NULL);
}
id只是声明过,没有初始化过!也许这只是一个错字,您想使用 i
作为 tid
的索引
解决方案应该是:
for(i=0;i<p;i++){
pthread_create(&tid[i],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
pthread_join(tid[i],NULL);
}
您的核心转储问题来源的答案已经得到解决,但要解决您提出或陈述的其他问题:
第一名:
关于您的陈述:我将它们作为指针,因为我不知道大小,用户将其作为参数提供。
通常,在 C 中,您可以通过使用 VLA 来避免在代码中使用 calloc
/malloc
。在 C99 及更高版本中可用。 (查看链接)
VLA a
VLA b
第二名:
关于您的声明:我知道它有点乱...
它确实 乱七八糟,但您可以考虑通过将大部分工作转移到一个函数中来清理内存 allocation/freeing 步骤:
long int **A,**B,**C;
int N;
...
//in main
N = atoi(argv[2]);
A = Create2D(N, N);
B = Create2D(N, N);
B = Create2D(N, N);
...
free2D(A, N);
free2D(B, N);
free2D(C, N);
long ** Create2D(int c, int r)
{
long **arr;
int y = 0;
arr = calloc(c, sizeof(long *));
for(y=0;y<c;y++)
{
arr[y] = calloc((2*y)+1, sizeof(long));
}
return arr;
}
void free2D(long **arr, int c)
{
int i;
if(!arr) return;
for(i=0;i<c;i++)
{
if(arr[i])
{
free(arr[i]);
arr[i] = NULL;
}
}
free(arr);
arr = NULL;
}
旁注:
你的记忆陈述没有绝对错误:
A = (long int**) malloc(N*sizeof(long int*));
然而,尽管 C++ 需要它,但没有理由在使用 C 时强制转换 malloc
、calloc
或 realloc
的 return。(See discussion here) 以下就足够了(在 C 中):
A = malloc(N*sizeof(long int*));
大家好, 我的代码有问题,我不知道如何解决(分段错误(核心已转储))!
所以我的老师要我编写一个程序来创建 N 个踏板并让它们做一些事情 calculations.I 有 3 个全局二维数组 A、B、C(我将它们作为指针,因为我不知道大小,用户将其作为参数提供)。我尝试在主函数中为它们分配内存。
所以问题是当我尝试在 "pthread_create(&tid[id],NULL,add,(void *)(long) i);" 中创建踏板时出现分段错误:(。 我不明白为什么 happening.I 尝试使用 gdb 命令,但结果是问题出在 pthread_create.
然而,当我在评论中添加数组(A、B、C)时,他们使用的 malloc 正在运行(但最终结果为 0)。
我正在使用一个虚拟盒子(如果有帮助,里面有 Ubuntu :D)。
以下是我目前写的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
long int p,N,Total_Sum;
long int **A,**B,**C;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t bar;
void * add(void *arg){
long int i,j,Local_Sum=0;
long int lines,start,end,id;
id = (long int)arg;
lines = N/p;
start = id*lines;
end = start+lines;
for(i=start;i<end;i++){
for(j=0;j<N;j++){
A[i][j] = 1;
B[i][j] = 1;
}
}
for(i=start;i<end;i++){
for(j=0;j<N;j++){
C[i][j] = A[i][j] * B[i][j];
Local_Sum += C[i][j];
printf("C[%ld][%ld] = %ld\n",i,j,C[i][j]);
}
}
pthread_mutex_lock(&mutex);
Total_Sum += Local_Sum;
pthread_mutex_unlock(&mutex);
pthread_barrier_wait(&bar);
pthread_exit(0);
}
int main(int argc, char *argv[]){
long int i,j,id;
pthread_t *tid;
if(argc!=3){
printf("Provide Number Of Threads And Size\n");
exit(1);
}
p = atoi(argv[1]);
tid = (pthread_t *) malloc(p*sizeof(pthread_t));
if(tid == NULL){
printf("Could Not Allocate Memory\n");
exit(1);
}
pthread_barrier_init(&bar,NULL,p);
N = atoi(argv[2]);
A = (long int**) malloc(N*sizeof(long int*));
B = (long int**) malloc(N*sizeof(long int*));
C = (long int**) malloc(N*sizeof(long int*));
for(i=0;i<N;i++){
A[i] = (long int*) malloc(N*sizeof(long int));
B[i] = (long int*) malloc(N*sizeof(long int));
C[i] = (long int*) malloc(N*sizeof(long int));
}
if((A==NULL) || (B == NULL) || (C == NULL)){
printf("Count Not Allocate Memory\n");
exit(1);
}
for(i=0;i<p;i++){
pthread_create(&tid[id],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
pthread_join(tid[id],NULL);
}
for(i=0;i<N;i++){
free(A[i]);
free(B[i]);
free(C[i]);
}
free(A);
free(B);
free(C);
printf("Final Result Is Equal To: %ld\n",Total_Sum);
return 0;
}
******我知道由于互斥锁和障碍,它变得有点混乱,但请向我询问进一步的规范:D.******
谢谢!!!!!!
我认为唯一的问题是以下几行中的索引:
for(i=0;i<p;i++){
pthread_create(&tid[id],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
pthread_join(tid[id],NULL);
}
id只是声明过,没有初始化过!也许这只是一个错字,您想使用 i
作为 tid
解决方案应该是:
for(i=0;i<p;i++){
pthread_create(&tid[i],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
pthread_join(tid[i],NULL);
}
您的核心转储问题来源的答案已经得到解决,但要解决您提出或陈述的其他问题:
第一名:
关于您的陈述:我将它们作为指针,因为我不知道大小,用户将其作为参数提供。
通常,在 C 中,您可以通过使用 VLA 来避免在代码中使用 calloc
/malloc
。在 C99 及更高版本中可用。 (查看链接)
VLA a
VLA b
第二名:
关于您的声明:我知道它有点乱...
它确实 乱七八糟,但您可以考虑通过将大部分工作转移到一个函数中来清理内存 allocation/freeing 步骤:
long int **A,**B,**C;
int N;
...
//in main
N = atoi(argv[2]);
A = Create2D(N, N);
B = Create2D(N, N);
B = Create2D(N, N);
...
free2D(A, N);
free2D(B, N);
free2D(C, N);
long ** Create2D(int c, int r)
{
long **arr;
int y = 0;
arr = calloc(c, sizeof(long *));
for(y=0;y<c;y++)
{
arr[y] = calloc((2*y)+1, sizeof(long));
}
return arr;
}
void free2D(long **arr, int c)
{
int i;
if(!arr) return;
for(i=0;i<c;i++)
{
if(arr[i])
{
free(arr[i]);
arr[i] = NULL;
}
}
free(arr);
arr = NULL;
}
旁注:
你的记忆陈述没有绝对错误:
A = (long int**) malloc(N*sizeof(long int*));
然而,尽管 C++ 需要它,但没有理由在使用 C 时强制转换 malloc
、calloc
或 realloc
的 return。(See discussion here) 以下就足够了(在 C 中):
A = malloc(N*sizeof(long int*));