QtConcurrent::run Access violation reading location
-
Hello all, I have a code
@for(int i=0;i<countThreads;i++)
{
QFuture<void> future = QtConcurrent::run(this,&MainWindow::thread);
threads.push_back(future);
}@@void MainWindow::thread()
{
while(lastLink < countLinks)
{
::EnterCriticalSection(&editLastLink);
int i = lastLink;
incLastLink();
::LeaveCriticalSection(&editLastLink);QString req = doRequest(links[i]); if(req.contains("something")) { ::EnterCriticalSection(&editGoodLink); out << links[i] << endl; incGoodLinks(); ::LeaveCriticalSection(&editGoodLink); } }}@
@QString MainWindow::doRequest(QString url)
{
QString out;
QTimer timer;
QNetworkAccessManager* manager = new QNetworkAccessManager;
QEventLoop loop;
QObject::connect(&timer,SIGNAL(timeout()),&loop,SLOT(quit()));
QObject::connect(manager,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
QNetworkReply* reply = manager->get(QNetworkRequest(QUrl(url)));
timer.start(TIMEOUT);
loop.exec();
if(!timer.isActive())
{
reply->abort();
}
else
{
if(reply->error() == QNetworkReply::NoError)
{
out = static_cast<QString>( reply->readAll() );
}
reply->close();
}
delete manager;
return out;
}@And for example after some minutes of work i get error
@Unhandled exception at 0x02e4c518 in progr.exe: 0xC0000005: Access violation reading location 0x76c29e98@
Where is an error? And how to fix it? -
Hi,
Your application is trying to read an invalid memory location.
Run you application through a debugger, it will show you where the error happens.
-
-
Out of curiosity, why don't you use QMutex to protect your data access ?
Also, I am surprised of this:
@out = static_cast<QString>( reply->readAll() )@
Why not use the QString::QString(const QByteArray) constructor ?
static_cast doesn't transform the QByteArray into a QString
-
@void MainWindow::thread()
{
while(lastLink < countLinks)
{
mutex1.lock();
int i = lastLink;
incLastLink();
mutex1.unlock();QString req = doRequest(links[i]); if(req.contains("something")) { mutex2.lock(); out << links[i] << endl; incGoodLinks(); mutex2.unlock(); } }}
@@QString MainWindow::doRequest(QString url)
{
QString out;
QTimer timer;
QNetworkAccessManager* manager = new QNetworkAccessManager;
QEventLoop loop;
QObject::connect(&timer,SIGNAL(timeout()),&loop,SLOT(quit()));
QObject::connect(manager,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
QNetworkReply* reply = manager->get(QNetworkRequest(QUrl(url)));
timer.start(TIMEOUT);
loop.exec();
if(!timer.isActive())
{
reply->abort();
}
else
{
if(reply->error() == QNetworkReply::NoError)
{
out = QString::QString( reply->readAll() );
}
reply->close();
}
delete manager;
return out;
}@ -
Is it the function you use to increment your lastLink variable ? (You might use a QAtomicInt for that)
-
Since it's pointer related, try to replace delete manager with
@manager->deleteLater();@And maybe check that reply is a valid pointer (could be something related to it since it's the only other pointer visible in your code).
On a related note, I don't know for sure but I think It's your job to delete reply.
-
Since it's a pointer:
@if (reply)@
Unless something is wrong, reply should either be NULL or pointing to a valid QNetworkReply (AFAIK, It shouldn't be NULL, but it's better to check to ensure that's not that that is causing you the access violation)
-
I edit the code
@QString MainWindow::doRequest(QString url)
{
QString out;
QTimer timer;
QNetworkAccessManager* manager = new QNetworkAccessManager;
QEventLoop loop;
QObject::connect(&timer,SIGNAL(timeout()),&loop,SLOT(quit()));
QObject::connect(manager,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
QNetworkReply* reply = manager->get(QNetworkRequest(QUrl(url)));
timer.start(TIMEOUT);
loop.exec();
if(!timer.isActive())
{
reply->abort();
}
else
{
if(!reply) ::Beep(1000,1000);
if(reply->error() == QNetworkReply::NoError)
{
out = QString::QString( reply->readAll() );
}
reply->close();
}
reply->deleteLater();
manager->deleteLater();
return out;
}@And i got error
!http://clip2net.com/clip/m0/1373183493-clip-9kb.png(1)!So, i never heard beep
-
I would check reply sooner, you might be calling abort on an invalid reply (though it would be strange)
-
Are you sure everything you are accessing is valid (like links[i]) ?
-
I runned it from cdb debugger. I see many errors, its showed at startup
@:0: предупреждение: Exception at 0x7c812aeb, code: 0x6ba: RPC server unavailable, flags=0x1 (execution cannot be continued) (first chance):0: предупреждение: Exception at 0x7c812aeb, code: 0x6ba: RPC server unavailable, flags=0x1 (execution cannot be continued) (first chance)
:0: предупреждение: Exception at 0x7c812aeb, code: 0x406d1388: Startup complete, flags=0x0 (first chance)
:0: предупреждение: Exception at 0x7c812aeb, code: 0x6ba: RPC server unavailable, flags=0x1 (execution cannot be continued) (first chance)
:0: предупреждение: Exception at 0x7c812aeb, code: 0x6a6: Invalid RPC server, flags=0x1 (execution cannot be continued) (first chance)@
So, on my pc RPC service is runned
-
Then are you sure your server is running and that you can make as much connection that you are trying ?
-
Then I would :
- First step: ensure the server is responding
- Second step: try to access the server with one query
- Third step: try with several queries in a row
- Forth step: Try to parallelize your queries
That might include refactoring your code so that for example you'll use QtConcurrent::map to call your function with all the queries from a QList rather than accessing them yourself