2016-02-20 62 views
1
void BTreeTest::testOneBTreeLeafNode() { 

BTreeLeafNode *test = new BTreeLeafNode(); 

BTreeData *info1 = new BTreeData; 
BTreeData *info2 = new BTreeData; 
BTreeData *info3 = new BTreeData; 
BTreeData *info4 = new BTreeData; 
BTreeData *info5 = new BTreeData; 


setInfo(&*info1, (char *)"Lester", (char *)"24", (char *)"student", 6, 2, 7); 
setInfo(&*info2, (char *)"David", (char *)"20", (char *)"student", 5, 2, 7); 
setInfo(&*info3, (char *)"June", (char *)"4", (char *)"toddler", 4, 1, 7); 
setInfo(&*info4, (char *)"Lisa", (char *)"18", (char *)"tutor", 4, 2, 5); 
setInfo(&*info5, (char *)"Savannah", (char *)"22", (char *)"barista", 8, 2, 7); 

correctData(&*info1, (char *)"Lester", (char *)"24", (char *)"student"); 
correctData(&*info2, (char *)"David", (char *)"20", (char *)"student"); 
correctData(&*info3, (char *)"June", (char *)"4", (char *)"toddler"); 
correctData(&*info4, (char *)"Lisa", (char *)"18", (char *)"tutor"); 
correctData(&*info5, (char *)"Savannah", (char *)"22", (char *)"barista"); 


delete info1; 
delete info2; 
delete info3; 
delete info4; 
delete info5; 

delete test; 

} 

這是我爲我正在嘗試構建的程序編寫的測試。但是,爲了讓我有更清晰可讀的測試,我需要一個輔助函數。這就是setInfo的用途。這是代碼爲:C++通過引用與幫助函數傳遞

void setInfo(BTreeData *info, char *name, char *age, char *occupation, int 
    nameSize, int ageSize, int occSize) { 

    strncpy(info->name, name, nameSize); 
    strncpy(info->age, age, ageSize); 
    strncpy(info->occupation, occupation, occSize); 
} 

這個問題是我試圖設置信息的價值。我試圖通過引用來傳遞信息,所以我可以設置信息。當我檢查xCode調試器時,它會正常工作,直到setInfo函數結束。不過由於某些原因,當我的代碼返回到testOneBTreeLeafNode繼續執行代碼的其餘部分時,信息內的值會發生變化。它有如下圖所示的額外垃圾垃圾。我通過參考傳遞的理解很差。有人能夠啓發我嗎?

enter image description here

通知大衛的年齡和職業如何應該是20和學生。它有20和學生,但也有其他不必要的垃圾。這是爲什麼發生?

在情況下,有必要在這裏是被B樹結構:

// 
// BTree.hpp 
// CS130FinalProject 
// 
// Created by Lester Dela Cruz on 2/19/16. 
// Copyright © 2016 Lester Dela Cruz. All rights reserved. 
// 

#ifndef BTree_hpp 
#define BTree_hpp 

#define M (5) 
#define L (3) 

#include <stdio.h> 

struct BTreeData { 
    char name[20]; 
    char age[3]; 
    char occupation[30]; 
}; 

struct BTreeLeafNode { 
    BTreeData dataItems[L]; 
}; 

struct BTreeInternalNode { 
    char keys[M-1][20]; 
    BTreeLeafNode *branch[M]; 
}; 

class BTree { 

}; 

#endif /* BTree_hpp */ 
+0

只是有些挑剔,但最好使用'const int M = 5;'和'const int L = 3'而不是'#define M(5)'和'#define L(3)' ,因爲後兩者不是類型安全的。與C不同,C++的'const'實際上是常量。的xD –

回答

1

這是因爲你沒有複製終止空字符。

您正在堆上分配BtreeData類的新實例。每個實例的初始副本都包含隨機二進制垃圾。在堆上分配的POD數據不會用零初始化。

然後你使用strncpy()來初始化這些字段。若要將age成員初始化爲「20」,那麼您將爲ageSize傳遞2,因此strncpy()將複製'2'和'0',但不是應該終止C風格字符串的尾部\ 0 。因此,您的調試器不會看到尾部0,然後繼續打印它找到的任何隨機垃圾,因爲正如我所說的,類實例是從堆中分配的,並且繼承了先前在堆分配內存中的任何隨機數據。

的善意批評的幾個其他位,只要大家注意:

所有的
setInfo(&*info1, (char *)"Lester", (char *)"24", (char *)"student", 6, 2, 7); 

首先,「& *」實現絕對沒有。它沒有任何區別。

其次,明確(char *)演員表建議不佳。您必須這樣做的原因是因爲字符串文字是const char s,並且您的setInfo()函數將char *作爲參數。

除了您的setInfo()不需要參數char *首先。讓我們改變setInfo()以const char *作爲參數,並擺脫這些醜陋,醜陋的演員陣容。

這看起來像一個更大的應用程序的一部分,所以也許有一個原因,你爲什麼傳遞一個明確的字符串長度計數,但沒有真正的原因。只要讓事情順其自然,使用strcpy()而不是strncpy(),並忘記字符數。

更好的是,因爲我們在這裏說的是C++,所以讓我們擺脫所有的char陣列,並用std::string s代替它們。普通char陣列是如此...上個世紀。

我們有協議嗎?