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 で埋めます。助けてください?

4

3 に答える 3

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

この行は非常に危険です。std::string は単純な古いデータ型ではありません。memcpy が正しく初期化できるかどうかを確認できません。c++ (またはプログラミング) の最も厄介な動作の 1 つである未定義の動作が発生する可能性があります。

さらに、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"); 

hash_array が newArr(std::vector) と同じ型の場合、コピーの方法は非常に簡単です。

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++ を新しい言語として扱うほうがよいでしょう。c とは異なる点が多すぎます。その上、code::blocks や QtCreator devc++ のようなまともな無料の IDE がたくさんあり、ほとんど死んでいるプロジェクトです。

C++ を初めて使用する場合は、C++ 入門書 5 を始めるのに適した本です。

于 2013-03-31T21:15:14.990 に答える
1

stringが実際にstd::string(そしておそらくそうでなくても) である場合、これはクラッシュします。文字列の新しい配列を作成し、古い文字列クラスを上にコピーしてから、古い文字列を解放しています。ただし、文字列クラスに割り当てられたメモリへの内部ポインタが含まれている場合、新しいメモリ割り当てを作成するのではなく、内部ポインタをコピーするだけであるため、二重解放が発生します。

このように考えてください。次のクラスがあるとします。

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;

この時点でptr2->bar、同じメモリを指していますptr1->barが、ptr1それが保持していたメモリは解放されています

std::vectorこれはサイズ変更を自動的に処理し、配列のコピーについてまったく心配する必要がないため、最良の解決策は a を使用することです。ただし、現在のアプローチを維持したい場合は、memcpy呼び出しを次のように変更する必要があります。

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

メモリをコピーするだけでなく、クラスのコピー コンストラクターを呼び出して、その内容の適切なコピーを作成します。

于 2013-03-31T21:19:00.783 に答える
0

犯人はmemcpy電話だと思います。stringchar配列をポインターで管理する複雑なタイプです(ちょうどあなたが今やっているように)。通常、文字列のコピーは代入演算子を使用して行われ、文字列の場合はそれ自体の配列もコピーします。しかし、memcpy は単純にバイトごとにポインターをコピーし、delete[] は文字列によって管理される配列も削除します。現在、他の文字列は BAAAD である削除された文字列配列を使用しています。

memcpy の代わりに std::copy を使用できます。さらに良いことに、std::vector を使用すると、これまでの動的メモリ処理の問題のほとんどを解決できます。

于 2013-03-31T21:23:06.740 に答える