【问题标题】:Code crashes on calling delete调用 delete 时代码崩溃
【发布时间】:2016-12-05 17:30:14
【问题描述】:

这可能是一个愚蠢的问题,但是为什么调用删除时这段代码会崩溃?通过阅读其他问题,我知道这可能会导致未定义的行为,但我不明白为什么。

#include <iostream>
using namespace std;

char* resize (char* result, int& size){
  char * temp;
  temp = new char [size*10];
  for (int i=0;i<size;i++) temp[i]=result[i];
  size*=10;
  //delete[] result;
  return temp;
}

void transform(char in[], const char p1[], const char p2[]){
  int resultlength=100, inputindex=0, outputindex=0;
  char* result = new char[resultlength];

  while (in[inputindex]){
    result[outputindex++]=in[inputindex++];

    if (inputindex>=resultlength) result = resize (result,resultlength);
  }
  in[outputindex--]=0;
  while(outputindex>=0) in[outputindex]=result[outputindex--];
  //delete[] result;
}


int main(){
  char  t[200]="123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345";
  transform(t,"hfgh","dfsdfds");
  int i=0;
  while(t[i]) cout<<t[i++];
  cout<<endl;
  return 0; 
}

【问题讨论】:

  • result = temp 对函数的调用者没有任何意义。通过引用传递该指针,或者可能利用函数的其他未使用的返回值。这个问题有 数百个 重复项,但标题、描述和内容大相径庭,很难确定一个。
  • 我已经改变,所以它传递一个指针的引用,它仍然在到达删除时崩溃。
  • 我现在感觉很愚蠢,但是是的,错字是个问题(除了另一个错误)。谢谢。

标签: c++ crash


【解决方案1】:

@WhozCraig 对钱的评论是正确的。问题的关键在于

delete[] result;

使调用函数中的指针成为悬空指针。

线

result=temp;

对调用函数中的指针没有任何作用。调用函数仍然有一个悬空指针。

解决方案 1

将参数更改为对指针的引用。

void resize (char*& result, int& size){
 ...
}

解决方案 2

将新分配的内存作为返回值返回。

char* resize (char* result, int& size){
   char * temp;
   temp = new char (size*10);
   for (int i=0;i<size;i++) temp[i]=result[i];
   size*=10;
   delete[] result;
   return temp;
}

并确保使用

result = resize(result, resultlength);

在调用函数中。

解决方案 3

不要使用char* result,而是使用std::string resultstd::vector&lt;char&gt; result

看到 MCVE 后更新

线

while(outputindex>=0) in[outputindex]=result[outputindex--];

导致未定义的行为。通过使用gcc -Wall,我得到以下诊断:

socc.cc: In function ‘void transform(char*, const char*, const char*)’:
socc.cc:22:62: warning: operation on ‘outputindex’ may be undefined [-Wsequence-point]
   while(outputindex>=0) in[outputindex]=result[outputindex--];

                                                          ^

将其更改为:

while(outputindex>=0)
{
   in[outputindex]=result[outputindex];
   --outputindex;
}

该程序对我来说运行良好。

【讨论】:

  • 使用std::vectorFFS。
  • 我期待这样的事情,你是对的,但我的代码中不是还有一个错误吗?因为我已经尝试了这两种解决方案,但代码仍然在删除时崩溃......
  • @user3019593,您需要发布minimal reproducible example,以便我们看到您所看到的内容。
  • 我已经编辑了我的帖子以添加 main.基本上这就是我此刻的全部代码。
  • 好的,正如 Avi Berger 指出的那样,有一个错字。你也错过了 :) 案件结案,非常非常感谢。
【解决方案2】:
  1. 结果可能为空,请务必检查函数顶部
  2. 您正在做的是删除调整大小的结果。但是由于指针不是通过引用传递的,因此 resize 函数之外的结果指针指向已删除的内存。所以要么通过引用传递指针,要么将其更改为
resize(char ** result,....){
   //Resize stuff
   delete result*;//Deleting the stuff pointed to by result
   result* = temp;// Assigning the pointer outside the function to temp
}

然后你会调用 resize like

resize(&result,resultlength)

编辑: 要更改调整大小以通过引用获取指针,请将声明更改为

resize(char*& result,...)

就是这样,比指针方法简单得多。

【讨论】:

  • 在 C++ 中,传递对指针的引用是首选的习惯用法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多