2013-03-31 4 views
1

동적으로 할당 된 문자열 배열의 크기를 조정하려고합니다. 여기에 코드가 있습니다!동적 문자열 배열 크기 조정

void resize_array() { 
    size_t newSize = hash_array_length + 100; 
    string* newArr = new string[newSize]; 

    fill_n(hash_array,newSize,"0"); //fills arrays with zeros 

    memcpy(newArr, hash_array, hash_array_length * sizeof(string)); 

    hash_array_length = newSize; 
    delete [] hash_array; 
    hash_array = newArr; 
} 

불행히도 작동하지 않아 세그먼트 오류가 발생합니다. 왜 어떤 생각? 이것은 기본적으로 선형 탐색 해시 테이블입니다. 여기서 0이있을 때마다 요소가 삽입됩니다. 따라서 fill_n을 사용하여 새로 만든 배열을 0으로 채 웁니다. 어떤 도움을 주시겠습니까?

+1

여기서 사용하는 언어와 세그먼트 화 오류가 발생한 줄을 말씀해 주시겠습니까? 감사. – Simon

+0

내가 사용하고있는 언어는 C++이며, 세그먼테이션 오류가 발생하는 행을 확인할 수 없습니다. 저는 dev-C++를 컴파일러로 사용하고 있으며 디버거에 문제가 있다고 생각합니다. –

+1

작성하지 않고 ['std :: string :: empty()'] (http://en.cppreference.com/w/cpp/string/basic_string/empty)를 사용하여 사용되지 않는 항목을 테스트하는 것이 더 간단하지 않습니까? 그리고 ""0 "'의 마법 값을 테스트 할 수 있습니까? – Blastfurnace

답변

4
memcpy(newArr, hash_array, hash_array_length * sizeof(string)); 

이 줄은 매우 위험, 표준 : : 문자열이 평범한 오래된 데이터 유형하지 않다, 당신이, 방어 적이기가 제대로 초기화 할 수 있는지 확인 할 수는 정의되지 않은 동작, 가장 중 하나가 될 수 있습니다 C++ (또는 프로그래밍)의 불쾌한 행동. hash_array가 newArr과 같은 유형 (있는 경우

게다가, 더 나은 및 솔루션 (시대의 대부분에서) 단지 사용, C++로 동적 문자열 배열을 만들 안전 벡터

//create a dynamic string array with newSize and initialize them with "0" 
//in your case, I don't think you need to initialize it with "0" 
std::vector<std::string> newArr(newSize, "0"); 

있다 표준 : : 벡터) 복사 방법은 매우 쉽습니다. 새로운 언어로

는 C++ 98

std::copy(hash_array.begin(), hash_array.end(), newArr.begin()); 

C++ 11

std::copy(std::begin(hash_array), std::end(hash_array), std::begin(newArr)); 

더 나은 치료 C는 ++, 너무 많은 일들이 다 다릅니다있다. 게다가, code :: blocks와 QtCreator와 같이 괜찮은 무료 IDE가 많이 있습니다. devC++는 거의 죽은 프로젝트입니다.

C++을 처음 사용하는 경우 C++ 입문서 5를 시작하는 것이 좋습니다.

+0

이 명령은 이전 memcpy 행과 동일한 작업을 수행합니까? C++로 시작한 C를 한 번도 해 보지 못했습니다. –

+0

아니요,이 코드는 문자열의 동적 배열 만 만들고 "0"으로 초기화합니다. hash_array의 유형을 알기 전에 hash_array를 newArr에 복사하는 방법을 모르겠습니다. – StereoMatching

1

string이 실제로 std::string (그리고 아마도 그렇지 않을지라도) 이는 충돌 할 것입니다. 새로운 문자열 배열을 만들고, 이전 문자열 클래스를 맨 위에 복사 한 다음 이전 문자열을 해제합니다. 그러나 문자열 클래스에 할당 된 메모리에 대한 내부 포인터가 포함되어있는 경우 새로운 메모리 할당을하지 않고 내부 포인터를 복사하기 때문에 이중 자유가 생깁니다.

이렇게 생각하십시오. ptr1->bar했던 것과 같은 메모리에,이 시점에서 ptr2->bar 점을

class foo 
{ 
    char* bar; 

    foo() { bar = malloc(100); } 
    ~foo() { free(bar); 
}; 

foo* ptr1 = new foo; 
foo* ptr2 = new foo; 
memcpy(ptr2, ptr1, sizeof(foo*)); 
delete ptr1; 

하지만 ptr1하고 개최 메모리는 가장 좋은 방법은을 사용하는 것입니다

을 해방되었습니다 상상 다음과 같은 클래스를했다 std::vector 이것은 자동으로 크기 조정을 처리하므로 배열 복사에 대해 걱정할 필요가 없기 때문입니다. 다만,이 클래스의 복사 생성자를 호출하고 그 내용의 적절한 복사본을 만들 것입니다 메모리를 복사하는 것보다 오히려

for (int i = 0; i < hash_array_length; ++i) 
{ 
    newArr[i] = hash_array[i]; 
} 

: 당신이 당신의 현재의 접근 방식을 유지하려는 경우, 당신은 다음에 memcpy 전화를 변경해야 .

+0

정말 고마워요! 이것은 실제로 도움이되고 실제로 이해됩니다! :디 –

0

나는 범인이 memcpy 전화라고 생각합니다. 은 (지금 당장하고있는 것처럼) 포인터로 char 배열을 관리하는 복잡한 타입입니다.일반적으로 문자열 복사는 대입 연산자를 사용하여 수행됩니다.이 대입 연산자는 문자열에 대해서도 자체 배열을 복사합니다. 그러나 memcpy는 바이트 단위로 바이트를 복사하고, delete []는 문자열로 관리되는 배열을 삭제합니다. 이제 다른 문자열은 BAAAD 인 삭제 된 문자열 배열을 사용합니다.

memcpy 대신 std :: copy를 사용하거나 더 나은 방법으로 std :: vector를 사용할 수 있습니다. 이는 대부분의 동적 메모리 처리 문제를 해결하는 방법입니다.