简体   繁体   English

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

[英]C++ passing by reference with helper functions

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;

}

This is a test I wrote for a program I'm trying to build. 这是我为要构建的程序编写的测试。 But, in order for me to have a cleaner more readable test I needed a helper function. 但是,为了让我有一个更清晰易读的测试,我需要一个辅助函数。 That's what the setInfo is for. 这就是setInfo的目的。 This is the code for that: 这是该代码:

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);
}

The problem with this is I'm trying to set the value of info. 问题是我正在尝试设置信息的值。 And I'm trying to pass by reference so I can set the info. 我正在尝试通过引用传递信息,以便我可以设置信息。 When I check through the xCode debugger it works correctly until the end of setInfo function. 当我检查xCode调试器时,它可以正常工作,直到setInfo函数结束。 For some reason though, when my code goes back inside testOneBTreeLeafNode to continue on through the rest of the code, the values inside the infos change. 但是由于某种原因,当我的代码返回到testOneBTreeLeafNode内部以继续执行其余代码时,信息内的值会更改。 It has extra unwanted garbage like the picture below. 它有多余的垃圾,如下图所示。 I have a poor understanding of passing by reference. 我对通过引用的理解不强。 Can someone enlighten me? 有人可以启发我吗?

在此处输入图片说明

Notice how David's age and occupation should be 20 and student. 注意David的年龄和职业应该是20岁还是学生。 It has 20 and student but also other unwanted garbage in it. 它有20和学生,但也有其他不需要的垃圾。 Why is this happening? 为什么会这样呢?

In case it's necessary here are are the BTree structs: 如果有必要,这里是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 */

This is because you're not copying the terminating null character. 这是因为您没有复制终止的空字符。

You are allocating a new instance of the BtreeData class on the heap. 您正在堆上分配BtreeData类的新实例。 The initial copy of each instance contains random binary garbage. 每个实例的初始副本包含随机的二进制垃圾。 POD data allocated on the heap does not get initialized with zeroes. 堆上分配的POD数据不会初始化为零。

Then you're using strncpy () to initialize the fields. 然后,您使用strncpy ()初始化字段。 To initialize the age member to "20", you're passing 2 for ageSize , so strncpy () is going to copy the '2' and the '0', but not the trailing \\0 that should be terminating C-style strings. 要将age成员初始化为“ 20”,您要为ageSize传递2,因此strncpy ()将复制'2'和'0',但不复制结尾的\\ 0,后者应终止C样式字符串。 So, your debugger does not see the trailing 0, then continues to print whatever random garbage it finds, because, as I said, the class instances were allocating from the heap and inherited whatever random data was previously, in the heap-allocated memory. 因此,调试器看不到尾随的0,然后继续打印找到的任何随机垃圾,因为正如我所说,类实例是从堆中分配的,并且继承了堆已分配内存中以前的任何随机数据。

A few other bits of well meaning criticism, as long as I have your attention: 只要您引起我的注意,还有一些其他善意的批评:

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

First of all, the "&*" accomplishes absolutely nothing. 首先,“&*”绝对没有完成任何事情。 It makes no difference whatsoever. 没什么区别。

Secondly, the explicit (char *) cast is poorly advised. 其次,建议不要使用显式(char *)强制转换。 The reason that you have to do it is because string literals are const char s, and your setInfo () function takes char * as parameters. 之所以必须这样做,是因为字符串文字是const char ,而setInfo ()函数将char *作为参数。

Except that your setInfo () does not need to take char * parameters in the first place. 除了您的setInfo ()不需要首先使用char *参数。 Let's change setInfo () to take const char * as parameters, and get rid of these ugly, ugly casts. 让我们更改setInfo ()以将const char *作为参数,并摆脱这些难看的,丑陋的演员表。

This looks like a part of a larger application, so perhaps there's a reason why you're passing an explicit string length count, but there's no actual reason for that. 这看起来像是较大应用程序的一部分,因此也许有理由要传递显式的字符串长度计数,但是没有实际原因。 Just let things take their natural course, use strcpy () instead of strncpy (), and forget about character counts. 只是让事情顺其自然,使用strcpy ()而不是strncpy (),而strncpy字符计数。

Better yet, since we're talking C++ here, let's get rid of all your char arrays, and replace them with std::string s. 更好的是,由于我们在这里谈论的是C++ ,所以让我们摆脱所有的char数组,并用std::string替换它们。 Plain char arrays are so ...last century. char数组是如此……上个世纪。

Do we have a deal? 我们有协议吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM