检查动态数组中是否确实存在值? C ++

时间:2012-04-23 01:51:37

标签: c++ c

我想知道在C ++中是否有办法检查动态数组的值是否确实存在。

int *x = new int[5];

好吧,所以我认为默认情况下x的每个值都是0.但是,问题是当我用值填充它时,我实际上可能会输入0.因此,这会导致混淆我们如果值真的存在与否(0似乎是成语告诉我们它是NULL,但在这种特殊情况下我不能使用那个成语,因为0可能是给我的值)。

是否有其他方法可以检查动态数组中的值是否未定义?

7 个答案:

答案 0 :(得分:3)

嗯,首先,正如Jonathon所说,无法保证数组将初始化为0。您可以单独初始化它,也可以使用int *x = new int[5]();为您做初始化。

至于你怎么知道哪些是有效的。最简单的方法是存储结构而不是int。像这样:

struct T {
    T() : valid(false), value(0) {
    }

    bool valid;
    int  value;
};

T *p = new T[5]; // each element will be initialized to false/0 because T has a constructor.

然后你可以这样做:

p[0].value = 10;
p[0].valid = true;

等等。

修改 作为一个更高级的选项,您可以使用运算符重载来自动设置valid标志,如下所示:

struct T {
    T() : valid(false), value(0) {
    }

    T &operator=(int x) {
        valid = true;
        value = x;
        return *this;
    }

    bool valid;
    int  value;
};

T *p = new T[5]; // each element will be initialized to false/0 because T has a 
p[1] = 10;       // p[1] is now true/10

基本上,为元素指定一个整数值会自动将其标记为有效。虽然在这个特定的例子中,我还没有演示如何将一个值“取消”回“无效”。这可能对您的用例或编码风格有意义,也可能没有意义,只是一些值得思考的东西。

答案 1 :(得分:2)

如果动态分配,则不会为您归零;您必须通过将所有条目设置为某个默认值来自行初始化阵列。如果零是有效条目,则考虑使用否定条目。如果所有正值和负值都是有效条目,则考虑使用包含整数值的结构,并将布尔标志初始化为false。

在C中,这将是:

typedef struct {
    bool valid;
    int  value;
} node;

node x[] = new node[5];

答案 2 :(得分:1)

如果你不能牺牲一个值,比如最小的负值或最大的正值int,意味着&#34;没有设置&#34;,你需要跟踪设置的内容旁边。在C ++中,您可以使用std::vector<bool>

int *x  = new int[5];
std::vector<bool> isSet(5, false);
if (!isSet[3]) {
    x[3] = 123;
    isSet[3] = true;
}

答案 3 :(得分:0)

如果他们认为您要使用的是密集/连续的,请使用std::vector(其size()成员将告诉您当前有效的项目数)。如果值很稀疏,请改用std::set

无论哪种方式,你最好忘记new T[size]存在,更不用说让自己受到实际使用它的疯狂。

答案 4 :(得分:0)

由于适当管理资源涉及的许多复杂性,我不会为此作业使用动态数组。在我看来,你应该看看std::vector,这会把你的代码变成这样的东西:

#include <vector>

...

    std::vector<int> x();
    x.resize(5);

现在,这将使您不再担心资源管理的瑕疵,并专注于实际重要的事情(即处理您的Xses)。

答案 5 :(得分:0)

  

但问题是,当我用值填充它时,我实际上可能会输入0.因此,这会导致混淆,告诉我们值是否真的存在

关于'0'是否真的存在并不存在混淆。如果阵列中有一个你没有放在那里的0,它仍然存在。恰好在数组中的零和放在那里的零之间没有区别。如果您需要区分已分配值的元素与未初始化的元素之间的区别,则必须在其他位置跟踪该信息。

bool *b = new bool[5](); // initialize the array to all false
int *x = new int[5]; // don't initialize the array
x[3] = 0; // set the fourth element in the array to 0
b[3] = true; // record that the fourth element in the array has been set

(注意,you shouldn't use raw arrays并且你不应该使用new / delete)


int *x = new int[5];
     

好的,所以我认为默认情况下,x的每个值都是0.

不是你构建那个数组的方式;数组中的int都没有被初始化。他们可以有任何价值。通常,当您构建“调试”模式时,内存将自动为您初始化,但C ++不会指定。

答案 6 :(得分:0)

除了我的另一个答案,另一种方法,如果你认为你的有效索引是稀疏的,那就是使用std::map作为一个关联数组,如下所示:

std::map<int, int> x;
x[0] = 10;
x[2] = 123;
// indexes 0 and 2 are set, the rest do not exist.

要测试是否预设了值,只需执行以下操作:

if(x.find(n) != x.end()) {
    // there is a value at index n
} else {
    // no value found at index n
}

如果您的有效索引是连续的,您也可以选择std::vector或我原来的答案。