调用delete时代码崩溃

时间:2016-12-05 17:30:15

标签: c++ crash

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

#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; 
}

2 个答案:

答案 0 :(得分:5)

@ 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<char> 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;
}

程序运行正常。

答案 1 :(得分:0)

  1. 结果可能为null,请务必在函数顶部检查
  2. 您正在做的是在调整大小时删除结果。但由于指针未通过引用传递,因此resize函数外部的结果指针指向已删除的内存。因此,要么通过引用传递指针,要么将其更改为
  3. 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(&result,resultlength)
    

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

    resize(char*& result,...)
    

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