2014-11-11 2 views
0

내가 프로그래밍에 초보자를 나는 최근에 내가 디버깅을 시도하고 만 오류 삭제 [] 소스에서 발생하는 발견디버그 어설 션 실패하는 경우에도 []

#include<iostream> 
using namespace std; 


void removeAllCharacters(char * , char *); 
void printArray(char*); 

void deleteArrays(char*,char*); 

int main() 
{ 
      char * source,*remove; 
      source=new char[18]; 
      remove=new char[10]; 

      source="Hello how are you"; 
      remove="Hi Its me"; 

      removeAllCharacters(source,remove); 
      printArray(source); 

      deleteArrays(source,remove); 
      system("pause"); 
      return 0; 
} 

void removeAllCharacters(char * source, char * remove) 
{ 
      int N1=strlen(source)+1; 
      int N2=strlen(remove)+1; 

      bool arr[128] = {false}; 

      for(int i=0;i<N2-1;i++) 
      { 
       arr[remove[i]]=1; 
      } 

      char *newSource=new char[N1]; 

      for(int i=0,j=0;i<N1-1;i++) 
      { 
       if(arr[source[i]]==0) 
       { 
        newSource[j++]=source[i]; 
       } 
      } 

      delete [] source; 
      source=newSource; 
      newSource=0; 
} 

void printArray(char* arr) 
{ 
      int N=strlen(arr)+1; 

      for(int i=0;i<N;i++) 
      { 
       cout << arr[i]; 
      } 

      cout << endl << endl; 
} 

void deleteArrays(char* arr1,char*arr2) 
{ 
      delete [] arr1; 
      arr1=0; 
      delete[]arr2; 
      arr2=0; 
} 

이 코드를 썼다; removeCharacters 함수에서. 나는 솔루션을 온라인으로 찾고 있지만 찾지 못했습니다.이 오류가 발생하는 이유는 무엇입니까? 내가 메인에서 동적 메모리를 할당했기 때문에 오류가 있습니까?하지만 함수에서 삭제하고 있습니까?

+0

어떤 오류가 표시됩니까? – Richard

+0

이것이 무엇을 의미하는지 잘 모르겠습니다 :'arr [remove [i]] = 1',하지만 그것은 정의되지 않은 행동을 일으킬 것입니다. – dlf

+4

'std :: string'을 사용하면 코드가 작동합니다. 포인터를 객체와 혼동하고 있습니다. –

답변

1
source="Hello how are you"; 
    remove="Hi Its me"; 

이것은 잘못되었습니다. 올바른 방법은 다음과 같습니다.

strcpy(source, "Hello how are you"); 
    strcpy(remove, "Hi Its me"); 

상수 문자열을 "삭제할"수 없습니다. "new"로 할당 된 배열/메모리를 삭제할 수 있습니다.

+0

"char"와 같은 간단한 유형의 경우 []가없는 삭제와 차이가 없습니다. 배열의 요소가 객체이고 소멸자에 대한 명시 적 호출이 필요한 경우 대괄호가 필요합니다. – i486

+1

@ i486 -'char * chars = new char [100]; 문자 삭제;는 정의되지 않은 동작입니다. 실제로는 작동 할 수도 있고, 구현의 작동 방식에 따라 100 바이트 할당에서 1 바이트 만 해제 될 수도 있습니다. 하지만 규칙은'new []'를 사용한다면'delete []'도 사용해야한다는 것입니다. – dlf

+0

@ i486 간단하고 내장 된 유형의 경우에도 저장 장치를 할당하는 데 사용 된 새 연산자와 일치하는 삭제 연산자를 사용해야합니다. new []를 통해 할당 된 경우 정의되지 않은 동작을 즐기지 않는 한 delete []를 통해 삭제해야합니다. – antred

5

new[]의 반환 값은 포인터 값입니다. 어떤 일이 일어나더라도 delete[]으로 전화를 걸 때 똑같은 포인터 값을 사용해야합니다.

source=new char[18]; 
    remove=new char[10]; 

    source="Hello how are you"; 
    remove="Hi Its me"; 

당신은 new[]로 할당하지만, 문자열 리터럴의 값으로 반환 값을 대체하고 있습니다 :

분명히 이것은 위의 규칙을 위반하는 것입니다. 즉, delete[]을 호출하는 데 필요한 포인터 값이 사라졌습니다. 우리는 데이터를 사용해 초기화 된 두 개의 버퍼를 생성

char str1[] = "Hello how are you"; 
    char str2[] = "Hi Its me"; 
    source=new char[sizeof(str1)]; 
    remove=new char[sizeof(str2)]; 
    strcpy(source, str1); 
    strcpy(remove, str2); 

참고 : 여기에

당신이 짓을해야하는지의 예입니다. 그런 다음 문자를 세는 대신 충분한 수의 저장 공간 (종료 null 포함)을 신중하게 할당하고 잘못된 결과를 얻을 수 있습니다.

그런 다음 strcpy 함수는 문자를 다른 버퍼로 복사합니다.

source=newSource 

당신은 그냥 할당 된 포인터가없는 반환 source 즉시 그 표시됩니다

당신은 또 다른 오류가 있습니다. 그 이유는 source이 값 매개 변수이므로 함수에 로컬로 할당됩니다. 함수에 전달되는 실제 값에 아무 것도하지 않으므로 모든 할당이 함수가 반환 될 때 연기가 퍼지기 만하면됩니다.

또한 C++ 프로그래밍의 초보자이기 때문에 문자열 데이터에 char *가 아닌 std::string을 사용할 수 있습니다. new[]을 사용하여 문자열을 만드는 것은 C++의 공룡 접근법입니다. 대신 std::string을 사용하십시오. 당신은 정말이 같은 문자열을 만드는 사업으로하지 노력해야한다 :

char *newSource=new char[N1]; 

이 그 delete[] 제대로 작동하도록 할당 된 메모리의 트랙을 유지 스파게티 같은 논리 때때로 메모리 누수로 연결합니다. 또한 언급 한 모든 문제가 대부분은 아니더라도 대부분 사라집니다. 할당 작업, 메모리 누수 없음 등

-1

소스는 값으로 전달됩니다.delete [] 소스 호출은 main 함수에서 소스에 영향을 미치지 않습니다.