gpt4 book ai didi

c++ - 返回时双重释放或损坏(出局)

转载 作者:行者123 更新时间:2023-11-27 22:57:48 25 4
gpt4 key购买 nike

我正在做一项涉及使用线程计算圆周率的作业。我已经使用 mutex 完成了这项工作并且工作正常,但我也想让这个版本工作。这是我的代码。

#include <iostream>
#include <stdlib.h>
#include <iomanip>
#include <vector>
#include <pthread.h>

using namespace std;

typedef struct{
int iterations; //How many iterations this thread is going to do
int offset; //The offset multiplier for the calculations (Makes sure each thread calculates a different part of the formula)
}threadParameterList;

vector<double> partialSumList;

void* pi_calc(void* param){
threadParameterList* _param = static_cast<threadParameterList*>(param);
double k = 1.0;
for(int i = _param->iterations * _param->offset + 1; i < _param->iterations * (_param->offset + 1); ++i){
partialSumList[_param->offset] += (double)k*(4.0/((2.0*i)*(2.0*i+1.0)*(2.0*i+2.0)));
k *= -1.0;
}
pthread_exit(0);
}

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

//Error checking
if(argc != 3){
cout << "error: two parameters required [iterations][threadcount]" << endl;
return -1;
}
if(atoi(argv[1]) <= 0 || atoi(argv[2]) <= 0){
cout << "error: invalid parameter supplied - parameters must be > 0." << endl;
return -1;
}

partialSumList.resize(atoi(argv[2]));

vector<pthread_t> threadList (atoi(argv[2]));
vector<threadParameterList> parameterList (atoi(argv[2]));

int iterations = atoi(argv[1]),
threadCount = atoi(argv[2]);

//Calculate workload for each thread
if(iterations % threadCount == 0){ //Threads divide evenly
for(int i = 0; i < threadCount; ++i){
parameterList[i].iterations = iterations/threadCount;
parameterList[i].offset = i;
pthread_create(&threadList[i], NULL, pi_calc, &parameterList[i]);
}
void* status;
for(int i = 0; i < threadCount; ++i){
pthread_join(threadList[i], &status);
}

}
else{ //Threads do not divide evenly
for(int i = 0; i < threadCount - 1; ++i){
parameterList[i].iterations = iterations/threadCount;
parameterList[i].offset = i;
pthread_create(&threadList[i], NULL, pi_calc, &parameterList[i]);
}
//Add the remainder to the last thread
parameterList[threadCount].iterations = (iterations % threadCount) + (iterations / threadCount);
parameterList[threadCount].offset = threadCount - 1;
pthread_create(&threadList[threadCount], NULL, pi_calc, &parameterList[threadCount]);
void* status;
for(int i = 0; i < threadCount-1; ++i){
pthread_join(threadList[i], &status);
cout << status << endl;
}
}

//calculate pi
double pi = 3.0;
for(int i = 0; i < partialSumList.size(); ++i){
pi += partialSumList[i];
}

cout << "Value of pi: " << setw(15) << setprecision(15) << pi << endl;

return 0;
}

该代码在大多数情况下都能正常工作。某些参数组合会导致我在 return 0 时出现双重释放或损坏错误。例如,如果我使用参数 10010,程序会创建 10 个线程并在每个线程上执行 10 次公式迭代,工作正常。如果我使用参数 104 程序创建 4 个线程,在 3 个线程上执行 2 次迭代,在第 4 个线程上执行 4 次迭代,工作正常。但是,如果我使用 53,程序将正确计算值甚至打印出来,但之后我立即收到错误。 173,以及 103 也会发生这种情况。我尝试了 157,但是当线程试图加入时我得到了一个 munmap_chunk(): invalid pointer 错误 - 虽然我认为这是另一个问题。

如果我不得不猜测,它与 pthread_exit 释放内存有关,然后在 return 时尝试再次释放相同的内存,因为我正在传递参数结构作为指针。我尝试了一些不同的事情,比如创建本地拷贝并将 parameterList 定义为指针 vector ,但它没有解决任何问题。我也尝试过在 return 之前eraseing 和clear vector ,但这也没有帮助。

最佳答案

我看到了这个问题:

你写的超出了 vector 的范围:

    vector<threadParameterList> parameterList (atoi(argv[2]));
//...
int threadCount = atoi(argv[2]);
//...
parameterList[threadCount].iterations = (iterations % threadCount) + (iterations / threadCount);
parameterList[threadCount].offset = threadCount - 1;

访问 parameterList[threadCount] 越界。

我没有在代码中看到调整 threadCount 的地方,因此它在整个代码段中保持相同的值。

提示:如果目标是访问容器中的最后一项,请使用 vector::back()。它始终适用于非空 vector 。

    parameterList.back().iterations = (iterations % threadCount) + (iterations / threadCount);
parameterList.back().offset = threadCount - 1;

关于c++ - 返回时双重释放或损坏(出局),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30898849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com