我应该将delete语句放在代码中的什么位置以消除内存泄漏? 我在Valgrind的C++程序中看到内存泄漏。我想知道我应该在哪里放置delete语句来远程执行它。多谢各位 #include <iostream> using namespace std; void showFloatArray(float f1[10]) { for (int i=0; i < 10; i++) cout << " " << f1[i]; cout << endl; } float *getFloatArrayOne() { float *floatArray = new float[10]; for (int i=0; i < 10; i++) floatArray[i] = (float) i; return(floatArray); } float *getFloatArrayTwo() { float myFloatArray[10]; float *floatArray = myFloatArray; for (int i=0; i < 10; i++) floatArray[i] = (float) i; return(floatArray); } int main() { float *f1 = getFloatArrayOne(); float *f2 = getFloatArrayTwo(); showFloatArray(f1); showFloatArray(f2); } #包括 使用名称空间std; void showFloatArray(浮点f1[10]){ 对于(int i=0;i,而不是将内存资源管理委托给内部处理的对象。

我应该将delete语句放在代码中的什么位置以消除内存泄漏? 我在Valgrind的C++程序中看到内存泄漏。我想知道我应该在哪里放置delete语句来远程执行它。多谢各位 #include <iostream> using namespace std; void showFloatArray(float f1[10]) { for (int i=0; i < 10; i++) cout << " " << f1[i]; cout << endl; } float *getFloatArrayOne() { float *floatArray = new float[10]; for (int i=0; i < 10; i++) floatArray[i] = (float) i; return(floatArray); } float *getFloatArrayTwo() { float myFloatArray[10]; float *floatArray = myFloatArray; for (int i=0; i < 10; i++) floatArray[i] = (float) i; return(floatArray); } int main() { float *f1 = getFloatArrayOne(); float *f2 = getFloatArrayTwo(); showFloatArray(f1); showFloatArray(f2); } #包括 使用名称空间std; void showFloatArray(浮点f1[10]){ 对于(int i=0;i,而不是将内存资源管理委托给内部处理的对象。,c++,memory-leaks,C++,Memory Leaks,任何时候用new创建指针时,必须确保在程序结束之前对该指针调用delete 例如: int main() { Object * obj = new Object; return 0; //leaky program! } int main() { Object * obj = new Object; delete obj; return 0; //non-leaky program! } 无论何时使用new创建指针,都必须确保在程序结束之前对该指

任何时候用
new
创建指针时,必须确保在程序结束之前对该指针调用
delete

例如:

int main()
{
    Object * obj = new Object;
    return 0; //leaky program! 
}


int main()
{
    Object * obj = new Object;
    delete obj;
    return 0; //non-leaky program! 
}

无论何时使用
new
创建指针,都必须确保在程序结束之前对该指针调用
delete

例如:

int main()
{
    Object * obj = new Object;
    return 0; //leaky program! 
}


int main()
{
    Object * obj = new Object;
    delete obj;
    return 0; //non-leaky program! 
}

当主函数终止时,您可能应该删除f1。第一个是在堆上动态分配的,它在执行期间保持分配状态,需要删除。至于第二个,您静态地声明它(在堆栈上),并且当函数getFloatArrayTwo()时终止时,它已解除分配向量,再次删除它我的结果是运行时双删除错误。在showFloatArray(f2)之后,您应该放置delete f1,泄漏应该消失


希望这能有所帮助。

您可能应该删除f1,因为主函数终止。第一个是在堆上动态分配的,在执行过程中保持分配状态,需要删除。第二个是静态声明(在堆栈上),当函数getFloatArrayTwo()时终止时,它已解除分配向量,再次删除它我的结果是运行时双删除错误。在showFloatArray(f2)之后,您应该放置delete f1,泄漏应该消失

希望这能有所帮助。

快速重写

最好让调用者进行分配。调用者知道如何分配和取消分配。如果您的函数(如库)进行分配,则调用者可能会怀疑是否必须取消分配对象

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// remove fixed size restriction on function
void print_array(float* f, size_t size) {
  for (size_t i=0; i < size; i++)
    cout << " " << f[i];
  cout << endl;
}

// pass in array
float* getFloatArrayOne(float f[], size_t size) {
  for (size_t i=0; i < size; i++)
    f[i] = (float)i;
  return f;
}

// pass in ptr - caller responsible for allocation and de-allocating
float *getFloatArrayTwo(float* f, size_t size) {
  for (size_t i=0; i < size; i++)
    *(f+i) = (float)i;  // dereference pointer + offset method 
  return f;
}

// You can use any algorithm you like to generate numbers
struct myincrementer {
  myincrementer(float startval) : n_(startval) {}
  float operator()() { return ++n_; }  // change to n_++ to start printing first value
  float n_;
};

int main()
{
  const int size = 10;
  float* floatArray = new float[size]();
  float *f1 = getFloatArrayOne(floatArray, size);

  float myFloatArray[size] = {0};
  float *f2 = getFloatArrayTwo(myFloatArray, size);
  print_array(f1, size);
  print_array(f2, size);
  delete [] floatArray;  // note [] form

  // More advanced approach
  vector<float> vec;
  myincrementer myi(0.0);
  generate_n(back_inserter(vec), 10, myi);
  std::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(std::cout, " "));
}
#包括
#包括
#包括
使用名称空间std;
//取消对函数的固定大小限制
无效打印数组(浮点*f,大小\u t大小){
对于(大小i=0;i
最好让调用者进行分配。调用者知道如何分配和取消分配。如果您的函数(如库)进行分配,则调用者可能会怀疑是否必须取消分配对象

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// remove fixed size restriction on function
void print_array(float* f, size_t size) {
  for (size_t i=0; i < size; i++)
    cout << " " << f[i];
  cout << endl;
}

// pass in array
float* getFloatArrayOne(float f[], size_t size) {
  for (size_t i=0; i < size; i++)
    f[i] = (float)i;
  return f;
}

// pass in ptr - caller responsible for allocation and de-allocating
float *getFloatArrayTwo(float* f, size_t size) {
  for (size_t i=0; i < size; i++)
    *(f+i) = (float)i;  // dereference pointer + offset method 
  return f;
}

// You can use any algorithm you like to generate numbers
struct myincrementer {
  myincrementer(float startval) : n_(startval) {}
  float operator()() { return ++n_; }  // change to n_++ to start printing first value
  float n_;
};

int main()
{
  const int size = 10;
  float* floatArray = new float[size]();
  float *f1 = getFloatArrayOne(floatArray, size);

  float myFloatArray[size] = {0};
  float *f2 = getFloatArrayTwo(myFloatArray, size);
  print_array(f1, size);
  print_array(f2, size);
  delete [] floatArray;  // note [] form

  // More advanced approach
  vector<float> vec;
  myincrementer myi(0.0);
  generate_n(back_inserter(vec), 10, myi);
  std::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(std::cout, " "));
}
#包括
#包括
#包括
使用名称空间std;
//取消对函数的固定大小限制
无效打印数组(浮点*f,大小\u t大小){
对于(大小i=0;iCUT< P>“现代”C++通常避免了使用<代码>新< /COD>和 Debug  >,而不是将内存资源管理委托给内部处理的对象。
然而,由于这是一项家庭作业,似乎值得学习的不仅仅是消除问题的良好实践,还有泄漏的技术细节和避免泄漏的正式要求,与有效执行这些要求的任何特定方法无关

这就是:当成功调用分配函数返回指针值,并且没有使用分配函数返回的值调用正确的解除分配函数时,就会发生内存泄漏。也就是说,当分配内存但未能解除分配内存时,就会发生内存泄漏

通过
malloc()
的分配必须通过
free()
解除分配。通过
new
的分配必须通过
delete
解除分配。通过
new[]
的分配必须通过
delete[]解除分配

int *x = malloc(sizeof(int)); // C code

if (x) {
  // allocation succeeded, you can use the resource and you should free() it
  // ... use
  free(x);
}


实际上 因此,修复或避免内存泄漏只需要“仅仅”您的程序为每次成功分配调用释放函数。然而,挑战在于,这很难以任意或特别的方式实现。为了在实践中避免泄漏,您需要建立易于管理的分配和释放模式调查和核实

因此,以下是一些让您开始学习资源管理实用性的建议:

跨多种语言管理资源的基本实践是定义“所有权语义”对于特定资源。定义用于确定程序的哪个部分负责任何特定分配资源的规则,以及用于确定如何将特定资源的责任从程序的一个部分转移到另一个部分的规则

通常,所有权语义是这样定义的,即程序中分配资源的部分负责分配资源。这似乎很明显,但也有其他选择。例如,一个程序可以指定一个实体负责清理所有内容,然后程序的其余部分只是随意分配,什么都没有与清理有关。但更常见的情况是,分配资源的任何人都要为此负责

例如,分配一些动态内存以执行其任务的函数在任务完成时也会释放该内存:

void foo(int n) {
  int *arr = malloc(n * sizeof(int));
  // ...
  free(arr)
}
另一种对已分配资源“承担责任”的方法是,在资源被关闭时,明确说明资源管理的要求。例如,需要分配内存并将该内存传递回调用方的函数可以指定“调用
foo()
的调用方必须调用
free\foo(foo\u结果)
当不再需要foo结果时。”

例外情况 对于正确的资源管理,必须在所有情况下设计所有的语义规则。C++支持的语言特征在历史上给人带来麻烦,使他们认为他们正确处理了资源管理职责,而实际上它们没有。例外情况

我不会详细讨论异常,但可以说它们是代码成功的原因
foo_t *foo() {
  foo_t *f = malloc(sizeof(foo_t));
  // ...
  return f;
}

void free_foo(foo_t *f) {
  free(f);
}
doSomething();
cleanup();