如果你打算在超出范围后保留变量,你在哪里调用delete?

时间:2014-10-26 12:40:26

标签: c++ dynamic pthreads new-operator

所以说我们有

struct Data
{
 int x;
 int y;
 int z;
}

void doWork()
{
  Data d;
  d.x = 1;
  d.y = 2;
  d.z = 3;
  pthread_t thrd;
  pthread_create(&thrd, NULL, someFunction, (void*)&d);
}

pthread_mutex_t outputLock = PTHREAD_MUTEX_INITIALIZER;//global scope

void* someFunction(void* arg)
{
  Data d = (Data*)arg;
  pthread_mutex_lock(&outputLock);
  std::cout << d->x->d->y+d->z;
  pthread_mutex_unlock(&outputLock);
}

这会导致未定义的行为,因为doWork()一旦将参数返回到someFunction()就会变得腐败。为了解决这个问题,我做了

Data* d = new Data(); 我的问题是,我不必担心内存泄漏,因为我没有打电话给delete吗?当程序结束时,它会自动清除任何内存泄漏吗?

可悲的是(据我所知),C ++ 11无法在Windows 8上开发(因为看起来Cygwin对此非常不满)。

3 个答案:

答案 0 :(得分:3)

你可以这样做:

struct Data
{
 int x;
 int y;
 int z;
}

void doWork()
{
  Data* dat = new Data;
  dat->x = 1;
  dat->y = 2;
  dat->z = 3;
  pthread_t thrd;
  if(pthread_create(&thrd, NULL, someFunction, (void*)dat) != 0)
      delete dat; // if thread not created need to cleanup here
}

void* someFunction(void* arg)
{
  Data* d = (Data*)arg;
  std::cout << d->x->d->y+d->z;
  delete d;
}

(更好)使用智能指针:

void* someFunction(void* arg)
{
    // From C++11 use std::unique_ptr
    std::auto_ptr<Data> d(reinterpret_cast<Data*>(arg)); // C++ style cast
    std::cout << d->x->d->y+d->z;
}

注意: std::auto_ptr已被C ++ 11中的std::unique_ptr取代

答案 1 :(得分:0)

是的,您必须担心内存泄漏。其中一个解决方案是删除Data*末尾的someFunction

答案 2 :(得分:0)

与您的代码对应的C ++答案将使用<thread>

#include <thread>
#include <iostream>

struct Data { int x; int y; int z; };

void someFunction(Data const & d)
{
    std::cout << d.x << ", " << d.y << ", " << d.z << "\n";
}

void doWork()
{
    std::thread(someFunction, Data{1, 2, 3}).detach();
}

你的原始版本和我的重写在创建之后忘记了线程,并且在程序退出之前依赖它最终完成。如果你想明确地加入线程,你必须在某处存储线程句柄。

在没有进一步同步的情况下写入std::cout也可能会导致意外结果。