随机段错误当使用全局二维变量而不是局部变量时
Random segfault When using global 2d variable instead of local one
这是完成了一半的代码,我应该将其转换为多线程代码。
我需要在所有线程中读取全局二维双变量“vector”。
所以我将它从 main 中的本地 var 转换为全局变量(如你所见,我在第 33 行评论了旧的)突然在仅此一次更改之后我的代码开始提供 运行dom 但经常出现段错误我将其改回到本地和 运行 代码 1000 次而不是一次崩溃,但是将这个本地 2d var 更改为全局将破坏一切
我真的不知道该怎么办,请帮助我。
# include <stdio.h>
# include <string.h>
# include <pthread.h>
# include <stdlib.h>
# include <math.h>
# define NUMBER_OF_COLUMNS 20
# define NUMBER_OF_CLASSES 4
# define NUMBER_OF_THREADS 4
# define NUMBER_OF_COLUMNS_PLUS_ONE 21 //STUPID C WONT LET ME MAKE GLOBAL VECTORS
double vectors[NUMBER_OF_CLASSES][NUMBER_OF_COLUMNS_PLUS_ONE];
double max[NUMBER_OF_COLUMNS], min[NUMBER_OF_COLUMNS];
pthread_t threads[NUMBER_OF_THREADS];
void * solve(void *id){
FILE *traincsv;
long tid;
tid = (long) id;
char buffer[1024];
char* token;
int EOFchecker = 1;
printf("Hello World! Thread ID, %ld\n", tid);
pthread_exit(NULL);
}
int main(){
FILE *traincsv, *traincsvnorm, *weightscsv;
char buffer[1024];
char* token;
double temp;
// double max[NUMBER_OF_COLUMNS], min[NUMBER_OF_COLUMNS];
int EOFchecker = 1;
int number_of_datas = 0, number_of_wrong_predictions = 0;
// double vectors[NUMBER_OF_CLASSES][NUMBER_OF_COLUMNS + 1];
double sum[NUMBER_OF_CLASSES];
int winner;
int return_code;
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
min[i] = INFINITY;
}
traincsv = fopen("train.csv","r");
traincsvnorm = fopen("trainnorm.csv","w+");
weightscsv = fopen("weights.csv","r");
// fprintf(traincsvnorm,"%s\n",buffer);
//load vectors to array last one is bias
fscanf(weightscsv,"%s",buffer);//first junk line
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
fscanf(weightscsv,"%s",buffer);
token = strtok(buffer,",");
for (size_t j = 0; j < NUMBER_OF_COLUMNS + 1; j++)
{
temp = atof(token);
vectors[i][j] = temp;
token = strtok(NULL,",");//next token of last string
}
}
//find min and max
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
if(max[i]<temp) max[i] = temp;
if(min[i]>temp) min[i] = temp;
token = strtok(NULL,",");//next token of last string
}
EOFchecker = fscanf(traincsv,"%s",buffer);
}
// Normilize
double maxMinusMin[NUMBER_OF_COLUMNS];
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
maxMinusMin[i] = max[i] - min[i];
}
EOFchecker = 1;
fseek(traincsv,0,SEEK_SET);
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
//reset sum of wieghts to bias;
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
sum[i] = vectors[i][NUMBER_OF_COLUMNS];
}
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
temp = (temp-min[i])/(maxMinusMin[i]);
for (size_t j = 0; j < NUMBER_OF_CLASSES; j++)
{
sum[j] += vectors[j][i] * temp;
}
token = strtok(NULL,",");//next token of last string
}
//check which vector has most points
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
if (sum[i] > sum[winner])
{
winner = i;
}
}
if(winner != atof(token)){
number_of_wrong_predictions ++;
}
number_of_datas ++;
EOFchecker = fscanf(traincsv,"%s",buffer);
}
// for(long tid = 0; tid < NUMBER_OF_THREADS; tid++)
// {
// printf("%ld\n",tid);
// return_code = pthread_create(&threads[tid],
// NULL, solve, (void *) tid);
// if (return_code)
// {
// printf("ERROR; return code from pthread_create() is %d\n",
// return_code);
// exit(-1);
// }
// }
printf("wrong predictions : %d \nall predictions : %d \n",number_of_wrong_predictions,number_of_datas);
fclose(traincsv);
fclose(traincsvnorm);
fclose(weightscsv);
pthread_exit(NULL);
}
这些是输入
train.csv
weights.csv
变量winner在第一次使用的时候没有初始化所以,
如果(总和[i]>总和[获胜者])
可能会访问 sum 之外的字段并导致段错误。
当向量数组在堆栈上时,获胜者可能具有较小的随机值并且不会导致段错误。
这是完成了一半的代码,我应该将其转换为多线程代码。
我需要在所有线程中读取全局二维双变量“vector”。
所以我将它从 main 中的本地 var 转换为全局变量(如你所见,我在第 33 行评论了旧的)突然在仅此一次更改之后我的代码开始提供 运行dom 但经常出现段错误我将其改回到本地和 运行 代码 1000 次而不是一次崩溃,但是将这个本地 2d var 更改为全局将破坏一切
我真的不知道该怎么办,请帮助我。
# include <stdio.h>
# include <string.h>
# include <pthread.h>
# include <stdlib.h>
# include <math.h>
# define NUMBER_OF_COLUMNS 20
# define NUMBER_OF_CLASSES 4
# define NUMBER_OF_THREADS 4
# define NUMBER_OF_COLUMNS_PLUS_ONE 21 //STUPID C WONT LET ME MAKE GLOBAL VECTORS
double vectors[NUMBER_OF_CLASSES][NUMBER_OF_COLUMNS_PLUS_ONE];
double max[NUMBER_OF_COLUMNS], min[NUMBER_OF_COLUMNS];
pthread_t threads[NUMBER_OF_THREADS];
void * solve(void *id){
FILE *traincsv;
long tid;
tid = (long) id;
char buffer[1024];
char* token;
int EOFchecker = 1;
printf("Hello World! Thread ID, %ld\n", tid);
pthread_exit(NULL);
}
int main(){
FILE *traincsv, *traincsvnorm, *weightscsv;
char buffer[1024];
char* token;
double temp;
// double max[NUMBER_OF_COLUMNS], min[NUMBER_OF_COLUMNS];
int EOFchecker = 1;
int number_of_datas = 0, number_of_wrong_predictions = 0;
// double vectors[NUMBER_OF_CLASSES][NUMBER_OF_COLUMNS + 1];
double sum[NUMBER_OF_CLASSES];
int winner;
int return_code;
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
min[i] = INFINITY;
}
traincsv = fopen("train.csv","r");
traincsvnorm = fopen("trainnorm.csv","w+");
weightscsv = fopen("weights.csv","r");
// fprintf(traincsvnorm,"%s\n",buffer);
//load vectors to array last one is bias
fscanf(weightscsv,"%s",buffer);//first junk line
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
fscanf(weightscsv,"%s",buffer);
token = strtok(buffer,",");
for (size_t j = 0; j < NUMBER_OF_COLUMNS + 1; j++)
{
temp = atof(token);
vectors[i][j] = temp;
token = strtok(NULL,",");//next token of last string
}
}
//find min and max
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
if(max[i]<temp) max[i] = temp;
if(min[i]>temp) min[i] = temp;
token = strtok(NULL,",");//next token of last string
}
EOFchecker = fscanf(traincsv,"%s",buffer);
}
// Normilize
double maxMinusMin[NUMBER_OF_COLUMNS];
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
maxMinusMin[i] = max[i] - min[i];
}
EOFchecker = 1;
fseek(traincsv,0,SEEK_SET);
fscanf(traincsv,"%s",buffer);//first line is just names
fscanf(traincsv,"%s",buffer);
while (EOFchecker != EOF)
{
token = strtok(buffer,",");
//reset sum of wieghts to bias;
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
sum[i] = vectors[i][NUMBER_OF_COLUMNS];
}
for (size_t i = 0; i < NUMBER_OF_COLUMNS; i++)
{
temp = atof(token);
temp = (temp-min[i])/(maxMinusMin[i]);
for (size_t j = 0; j < NUMBER_OF_CLASSES; j++)
{
sum[j] += vectors[j][i] * temp;
}
token = strtok(NULL,",");//next token of last string
}
//check which vector has most points
for (size_t i = 0; i < NUMBER_OF_CLASSES; i++)
{
if (sum[i] > sum[winner])
{
winner = i;
}
}
if(winner != atof(token)){
number_of_wrong_predictions ++;
}
number_of_datas ++;
EOFchecker = fscanf(traincsv,"%s",buffer);
}
// for(long tid = 0; tid < NUMBER_OF_THREADS; tid++)
// {
// printf("%ld\n",tid);
// return_code = pthread_create(&threads[tid],
// NULL, solve, (void *) tid);
// if (return_code)
// {
// printf("ERROR; return code from pthread_create() is %d\n",
// return_code);
// exit(-1);
// }
// }
printf("wrong predictions : %d \nall predictions : %d \n",number_of_wrong_predictions,number_of_datas);
fclose(traincsv);
fclose(traincsvnorm);
fclose(weightscsv);
pthread_exit(NULL);
}
这些是输入 train.csv weights.csv
变量winner在第一次使用的时候没有初始化所以,
如果(总和[i]>总和[获胜者])
可能会访问 sum 之外的字段并导致段错误。
当向量数组在堆栈上时,获胜者可能具有较小的随机值并且不会导致段错误。