1. 程式人生 > >.exe 已觸發了一個斷點。

.exe 已觸發了一個斷點。

這是我第一次碰到這種問題,查了很多資料,大家都說是記憶體越界導致的,但是我寫的這個程式已經大概5000行了,在哪個地方越界的?這個很難找。於是我把整個程式中所有存在new的地方全部檢視一遍,確實找到了一些越界的地方。可是修改後仍然這樣。更奇怪的是,這個錯誤並不是一定會在某個地方出現,而是出現的位置帶有一定的隨機性,但都是在申請記憶體的時候。無奈,用VS2013的反彙編跟蹤到出問題的地方,是一句 jmp XXXX。看來問題很清楚了。程式需要跳轉到一個地方去,但是這個地方的記憶體有問題。
面對這麼大的程式,去找是誰把堆疊裡面的東西搞亂了,還是相當困難了。逐步縮小範圍,我大概找出來,是一個類例項化的時候,申請了一些記憶體,然後下次再申請的時候就出錯了。但是這並不是原因。
    this->diameterNum = _diameterNum;
    this->isArtery = true;
    this->isVesselDark = true;
    this->isVesselSelect = false;
    this->isVesselValid = true;
    isCenterHighlight = new bool[diameterNum];  
    isCenterValid = new bool[diameterNum];
    side1 = new double[2 * diameterNum];
    side2 = new
double[2 * diameterNum]; center = new double[2 * diameterNum]; angles = new double[diameterNum]; memset(isCenterHighlight, false, diameterNum * sizeof(bool)); memset(isCenterValid, true, diameterNum * sizeof(bool)); memset(side1, 0, 2 * diameterNum * sizeof(double)); memset
(side2, 0, 2 * diameterNum * sizeof(double)); memset(center, 0, 2 * diameterNum * sizeof(double)); memset(angles, 0, 2 * diameterNum * sizeof(double));

乍一看,這程式碼沒啥問題吧。new 應該沒錯,看來只可能是 memset 了。於是我把memset全部註釋掉,程式沒問題了。可是我需要把這片記憶體初始化啊!而且 memset 是為啥出問題的還沒找到。於是我又把這些 memset 一個一個去掉註釋來除錯,發現在最後一句出問題了。再仔細一看,天啊,我memset越界了!這個就是元凶!但是memset越界就會導致堆疊損壞嗎?不一定!

    int * x0 = new int[LENGTH];
    int * x1 = new int[LENGTH];
    int * x2 = new int[LENGTH];
    memset(x0, 0, 3 * LENGTH * sizeof(int));
    int * x3 = new int[LENGTH];

這段程式碼明顯是越界了,但是沒報錯,也沒崩潰。有可能是memset如果把某個指標的指向位置置為0了。看來memset確實要謹慎使用。