OR博客
sizeof踩坑记录
OrdinaryRoad
创建于:2023-07-10 18:12:15
新疆
0
11
80
0
好久没用C/C++了,今天尝试着用C++写个二叉树递归前序遍历的代码,调试半天,发现变量总会莫名其妙地自己变化
### 结构体定义 ```cpp typedef struct BTreeNode { // 4,填充对齐到8 DATA_TYPE data; // 8 + 8 struct BTreeNode *lChild, *rChild; } BTreeNode, *BTree; ``` ### 初始化代码 ```cpp BTree createBTree(DATA_TYPE value) { BTree bTree = (BTree) malloc(sizeof (BTreeNode)); bTree->data = value; bTree->lChild = nullptr; bTree->rChild = nullptr; return bTree; } void setBTreeChild(BTree &node, BTree left, BTree right) { node->lChild = left; node->rChild = right; } BTree initBTree1() { BTree node1 = createBTree(1); BTree node2 = createBTree(2); BTree node3 = createBTree(3); BTree node4 = createBTree(4); BTree node5 = createBTree(5); BTree node6 = createBTree(6); BTree node7 = createBTree(7); BTree node8 = createBTree(8); BTree node9 = createBTree(9); BTree node10 = createBTree(10); BTree node11 = createBTree(11); BTree node12 = createBTree(12); BTree node13 = createBTree(13); BTree node14 = createBTree(14); BTree node15 = createBTree(15); setBTreeChild(node1, node2, node3); setBTreeChild(node2, node4, node5); setBTreeChild(node3, node6, node7); setBTreeChild(node4, node8, node9); setBTreeChild(node5, node10, node11); setBTreeChild(node6, node12, node13); setBTreeChild(node7, node14, node15); return node1; } ``` ### 问题复盘 `sizeof` 如果也用 `BTree` 就会出现问题,这问题也太隐蔽了;因为 `BTree` 其实是一个指向 `BTreeNode` 结构体的指针类型变量,指针变量长度只有8字节,而 `BTreeNode` 实际至少 `4+8+8=20字节` ,经过对齐填充后变为 `24字节` ```cpp // 8 size_t i2 = sizeof(BTree); // 24 size_t i3 = sizeof(BTreeNode); // 重点在这行代码,实际size=20,填充后为24 BTree bTree = (BTree) malloc(sizeof (BTreeNode)); ``` 因此正确申请内存的写法是 `malloc(sizeof (结构体原名))`,手动改为 `BTree bTree = (BTree) malloc(20);` 后,程序也可以正常运行 ```bash 1 2 4 8 9 5 10 11 3 6 12 13 7 14 15 Process finished with exit code 0 ``` ### 其余代码 ```cpp #include "cstdio" #include "cstdlib" using namespace std; #define DATA_TYPE int int main() { // 初始化二叉树 BTree b1 = initBTree1(); preOrder(b1); return 0; } void visit(BTree pNode); void preOrder(BTree bTree) { if (bTree == nullptr) { return; } visit(bTree); preOrder(bTree->lChild); preOrder(bTree->rChild); } void visit(BTree pNode) { if (pNode == nullptr) { return; } printf("%d\t", pNode->data); } ```
评论