C ++通过引用传递辅助函数

时间:2016-02-20 03:03:15

标签: c++ pass-by-reference

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的用途。这是代码:

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个学生,还有其他不需要的垃圾。为什么会这样?

如果这里必要的是BTree结构:

//
//  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 */

1 个答案:

答案 0 :(得分:1)

这是因为你没有复制终止空字符。

您正在堆上分配BtreeData类的新实例。每个实例的初始副本包含随机二进制垃圾。在堆上分配的POD数据不会用零初始化。

然后您使用strncpy()初始化字段。要将age成员初始化为“20”,您为ageSize传递2,因此strncpy()将复制'2'和'0',但不会尾随\ 0应该是终止C风格的字符串。因此,你的调试器没有看到尾随0,然后继续打印它找到的任何随机垃圾,因为,正如我所说,类实例是从堆分配并继承了以前在堆分配的内存中的随机数据。

只要我引起你的注意,还有一些其他好的批评意见:

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

首先,“&amp; *”完全没有任何结果。它没有任何区别。

其次,明确的(char *)演员表现不佳。您必须这样做的原因是因为字符串文字是const char s,而您的setInfo()函数需要char *作为参数。

除了setInfo()首先不需要char *个参数。让我们改变setInfo()以const char *作为参数,并摆脱这些丑陋,丑陋的演员阵容。

这看起来像是一个更大的应用程序的一部分,所以也许有一个原因,你传递一个显式的字符串长度计数,但没有实际的原因。只是让事情采取自然的方式,使用strcpy()而不是strncpy(),并忘记字符数。

更好的是,由于我们在这里谈论C++,让我们摆脱所有char数组,并用std::string替换它们。简单的char阵列是如此......上个世纪。

我们有交易吗?