2013-03-27 84 views
2

我有一個小的C++程序未能分配超過2880與malloc。聲明:Windows 7 64位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++ 

我知道,使用的malloc在C被勸阻++和我打算無論如何要改寫這個編制,但我還是想知道這是爲什麼不工作。當我用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工作,但沒有第二個。如果我更改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; 
} 
+0

gcc和mingw會是什麼版本? – scones 2013-03-27 13:27:40

+9

在其他地方看起來像未定義的行爲。 – chris 2013-03-27 13:27:51

+0

什麼機器? – 4pie0 2013-03-27 13:27:58

回答

1

謝謝大家,

事實證明,我在寫分配的內存(有點x和y的混亂)之外。奇怪的是,該計劃一直工作到現在(幾個月24/7),並做我一直期待的。它可以解釋一些我無法解釋的奇怪的東西。

現在我會反正用標準的C++內存分配來重寫代碼。

0

它看起來對我來說,你的堆在你的程序得到破壞別的地方(可能是在在main那個大循環。你可以做的第一件事就是開始打開警告-Wall-Wnon-virtual-dtor在最低限度,然後修復它們。

如果你有機會到Linux最好的辦法是下運行Valgrind的這一點,並驚訝,因爲它會告訴你到底在那裏你覆蓋內存。

如果您有權訪問Windows上的Purify($$$),也可以幫助您。還有內存檢查malloc庫可用,您可以使用。

如果沒有這些工具可用,您將不得不自己診斷,試圖刪除代碼段,看看它是否仍然崩潰。

+0

標誌'-Wall'和'-Wnon-virtual-dtor'不會警告任何事情(除了未使用的變量)。將嘗試在debian(但我想我不會有同樣的問題)。無論如何,我最終需要它在Windows中運行。 – petter 2013-03-27 14:54:43

0

如果我冒昧猜測,這是你沒有正確分配sky->data或其子指針。

這在兩個步驟來完成:

  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]; 
    

Yo你當然可以使用malloc而不是new

當釋放數據時,可以以相反的方式進行:首先釋放循環中的每個子數組,然後是主數組。