2

で2880以上を割り当てることができない小さなC++mallocプログラムがあります。ステートメント:

void* tmpptr = malloc(2881);

クラッシュしますが

void* tmpptr = malloc(2880);

しませ。毎回!

私はMinGWを使用してコンパイルしています

g++ -std=c++0x -pedantic -Wall -Wextra -g -D_GLIBCXX_DEBUG -static-libgcc -static-libstdc++

C ++ではの使用mallocが推奨されていないことを知っており、とにかくこれを書き直す予定ですが、なぜこれが機能しないのかを知りたいと思います。gccでコンパイルしたときも同じコードが機能しています。

更新:これは主な関数呼び出しです:

image * img = readPPM("pic/pic.ppm");
bw_image * sky = skyline(img, ref);
cont * lin = contour(sky, 0); // <-- chash
...

そして、関数は次のように始まります。

#include <cstdlib>
cont * contour(const bw_image * img, const char wrap) {
    int test = 2880;
    void* ptr1 = malloc(test);
    void* ptr2 = malloc(test);
...

これで、最初のものは機能しますmallocが、2番目のものは機能しません。変更test = 1440;しても同じ結果になります。だが; test = 140;すでに最初mallocは失敗します。

私はスタンドアロンとしてコードを試しました:

int main(int argc, char *argv[]) {
    int size = 2881;
    void* tmpptr;
    printf("Allocating, %d\n", size);
    tmpptr = malloc(size);
    printf("Allocated %d bytes successfully\n", size);
}

そしてそれは問題なく動作するので、それはそれを行う上で何かのようmainです。

rem_artifactsこんな風に見える

void rem_artifacts(bw_image * sky) {
    for (int y = 0; y < sky->y; ++y) for (int x = 0; x < sky->x; ++x) {
        int xp = x - 1, xn = x + 1;
        if (xp < 0) xp = sky->x - 1;
        if (xn == sky->x) xn = 0;
        int c = sky->data[x][y];  // this is wrong
        if (
            (y == 0 || sky->data[x][y-1] != c) &&  // and this
            (y == sky->y-1 || sky->data[x][y+1] != c) && // and this
            sky->data[xp][y] != c &&  // and this
            sky->data[xn][y] !=c  // and this
        ) sky->data[x][y] = !c; // and this
    }
}
bw_image * skyline(const image * img, const image * ref) {
    double tilt = 114.0 - 90.0;
    double pi = 3.14159265358979323846;
    double chang = 360.0 / 2.0 / pi;
    //double sint = sin(tilt / chang);
    //double cost = cos(tilt / chang);
    bw_image * sky = (bw_image*)malloc(sizeof(bw_image));
    sky->x = img->x;
    sky->y = img->y;    //  
    double cos30 = sqrt(3)/2;
    int lim0 = (int)((double)(img->y) / 2.0 + (double)(img->x) * tan(tilt/chang) * cos30);
    sky->data = (char**)malloc(sizeof(char*) * sky->y);
    for (int y = 0; y < sky->y; ++y) {
        sky->data[y] = (char*)malloc(sizeof(char) * sky->x);
        for (int x = 0; x < sky->x; ++x)
            sky->data[y][x] = !(y < lim0 && colour_dist_sq(img->data[y][x], ref->data[y][x]) < 5000.0);
    }
    rem_artifacts(sky);
    return sky;
}
4

3 に答える 3

2

みなさん、ありがとうございました、

割り当てられたメモリの外に書き込んでいたことがわかりました(少しaxとyの混乱)。奇妙なことに、このプログラムは今まで(24時間年中無休で何ヶ月も)機能していて、私が期待していたことを実行しています。しかし、私が説明できなかったいくつかの奇妙なことを説明することはできます。

とにかく、標準のC++メモリ割り当てを使用してコードを書き直します。

于 2013-03-27T19:47:18.603 に答える
0

プログラムのどこかでヒープが破損しているように見えます(おそらく、の大きなループ中にmain。最初にできることは、警告-Wallをオンに-Wnon-virtual-dtorして、最小限に抑えてから修正することです。

Linuxにアクセスできる場合、最善の策は、これをvalgrindで実行し、メモリを上書きしている場所を正確に教えてくれるので驚かれることです。

または、WindowsでPurify($$$)にアクセスできる場合は、それも役立つ可能性があります。使用できる可能性のあるメモリチェックmallocライブラリも利用できます。

これらのツールのいずれも使用できない場合は、コードのセクションを削除して、それでもクラッシュするかどうかを確認することにより、自分で診断を行う必要があります。

于 2013-03-27T14:46:08.290 に答える
0

思い切って推測すると、適切に割り当てられていないsky->dataか、そのサブポインタが割り当てられていないということです。

これは2つのステップで実行する必要があります。

  1. 最初に割り当てるsky->data

    sky->data = new char*[some_x_size];
    
  2. 次に、すべてのサブアレイを個別に割り当てる必要があります。

    for (int x = 0; x < some_x_size; x++)
        sky->data[x] = new char[some_y_size];
    

もちろん、mallocの代わりに使用することもできnewます。

データを解放するときは、逆の方法で行います。最初にループ内の各サブ配列を解放し、次にメイン配列を解放します。

于 2013-03-27T15:00:39.063 に答える