如果您希望变量在超出范围后保留,那么您将在哪里调用delete

Where do you call delete if you intended for variables to remain after going out of scope?

本文关键字:在哪里 delete 调用 保留 变量 希望 范围 如果      更新时间:2023-10-16

所以说我们有

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似乎对它很有缺陷)。

您可以这样做:

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取代

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

对应于代码的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也可能导致意外的结果。