2
#include <iostream>

using namespace std;

int main (int args, char **argv) {
    char *data = new char(16);
    for (int i = 0; i < 16; ++i) {
        data[i] = i; // works fine when commented out, also fails when data[i] = 0
    }

    char *res = new char (10);
    delete[] res;
    return 0;
}

エラーが発生します。自分で確認してください: http://ideone.com/AgZhZB

*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x09377018 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb7519ee2]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb76f751f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdaPv+0x1b)[0xb76f757b]
./a.out[0x80485af]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb74bd4d3]
./a.out[0x80484b1]

私には手がかりがありません。どんな助けでも大歓迎です。

4

3 に答える 3

10

交換

char *data = new char(16);

char *data = new char[16];

あなたが今持っているものは、シングルcharを割り当て、それを に初期化し16ます。配列を割り当てるには、上記のように角括弧を使用する必要があります。

同様に、

char *res = new char(10);

char *res = new char[10];
于 2013-03-06T08:07:38.847 に答える
3

正しい動作は、明らかに、使用しないことnewです。

#include <vector>

int main () {
    std::vector<char> data{16};
    for (int i = 0; i < 16; ++i) {
        data.at(i) = i;
    }

    std::vector<char> res{10};
    return 0;
}

注:data{10}表記法は C++11 の初期化構文です。ほとんど同等ですdata(10)が、コンパイラによってより簡単に解析されます。

于 2013-03-06T08:20:47.857 に答える
1

コードで「奇妙」になる可能性がある唯一のことは、最初に境界外アクセスを介して未定義の動作を呼び出していることです。

char *data = new char(16); // pointer to single char, value 16
for (int i = 0; i < 16; ++i) {
    data[i] = i; // out of bounds access: UNDEFINED BEHAVIOUR
}

delete[]次に、必要なときに呼び出すことによってdelete:

char *res = new char (10); // pointer to single char, value 10
delete[] res; // Oops, UNDEFINED BEHAVIOUR

未定義の動作を取得すると、何かが起こる可能性があります。再現可能である必要はないため、「奇妙」に見える場合があります。

于 2013-03-06T08:17:14.287 に答える