4

[編集]

さて、それは理にかなっているので、sharptoothとCashCowに感謝します。constとして割り当てられたデータを削除することはできません。これにより、文字列リテラルが問題から外れます。したがって、初期化を次のように変更すると、次のようになります。

char **groups = new char*[2];

char *s1 = new char[10];
char *s2 = new char[10];
char c1 = 'a';
char c2 = 'b';
for(int i = 0; i < 9; i++)
{
    s1[i] = c1;
    s2[i] = c2;
}
s1[9] = NULL;
s2[9] = NULL;

groups[0] = s1;
groups[1] = s2;

forループをハードコーディングして、i=1とi=2のみを繰り返すようにすると、すべてが機能します。

int arraySize = sizeof arr / sizeof *arr;配列がローカルではなくnew[]で割り当てられている場合にのみ、機能するように見えることに気付きました。これは、元のchar ** groups;変数がポインターに減衰するためですよね?

今、私は疑問に思っていますが、データが定数であるかどうかを判断する方法はありますか?


[オリジナル]

配列とポインタは悪であり、ベクトルとリンクリストと呼ばれるこれらの素晴らしいものがあることを私は知っています。

しかし、私はメモリ管理に関しては初心者であり、少しマゾヒスティックな感じがします。C文字列の配列を作成するとします。この質問type a = new type[len];とFAQ-Liteから、と一致する必要があることがわかりますdelete[] a;。またはそう思います。

FAQ-Liteはここでジャグ配列の管理について話しますが、彼は行列に焦点を合わせており、それが私が行っていることに当てはまるかどうかはわかりません。

このコードは私には理にかなっていますが、でのアサーション(Visual Studio 2008でのデバッグ)に失敗しますdelete[] a;。これの何が問題になっていますか?また、このタスクを実行するにはどうすればよいですか?

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    // Initialize array of C-strings
    char *groups[] = {"testing1", "testing2"};

    // Sanity check
    cout << groups[0] << endl;
    cout << groups[1] << endl;

    // Compute size
    int arrsize = sizeof groups / sizeof groups[0];
    cout << arrsize << endl;

    for (int i = 0; i < arrsize; i++)
    {
        // Since each string is a char array, free string memory with delete[]
        cout << "Deleting element #" << i << endl;
        delete[] groups[i];
    }
    cout << "Freeing pointer array." << endl;

    // Free the memory storing the pointers
    delete[] groups;

    return 0;
}
4

2 に答える 2

9

文字列リテラルの割り当てを解除しようとしました-これは未定義の動作です:

char *groups[] = {"testing1", "testing2"};
delete[] groups[i];

delete[]によって返されるポインタのみを呼び出しますnew[]

于 2010-11-29T09:43:02.690 に答える
1

リテラル文字列は、「testing1」のような式です。これらは const char * 型です。それらは変更できず、削除できません。通常、実際のテキストは、プログラムの静的な読み取り専用メモリ領域にあります。

次のように書き込み可能な char 配列を作成できます。

char group[] = "testing1";

これは変更可能ですが、削除することも、拡張して大きくすることもできません。また、ローカル スコープがあるため、関数から返すことはできません。

于 2010-11-29T09:54:57.293 に答える