简体   繁体   English

C ++可变参数问题

[英]C++ variadic parameters issue

Take a look at this code: 看看这段代码:

StdAfx.h: StdAfx.h中:

#pragma once

#include <stdarg.h>

template<class T>
class DArray {
private:
    T* elements;
    int dimensions, length;
    int* lengths;

public:
    DArray() {
        dimensions = 0;
        length = 0;
    }

    DArray(int dims, ...) {
        va_list args;
        va_start(args, dims);
        dimensions = dims;
        lengths = new int[dims];
        length = 1;
        for (int i = 0; i < dims; i++) {
            lengths[i] = va_arg(args, int);
            length *= lengths[i];
        }
        va_end(args);
        elements = new T[length];
    }

    T get(...) {
        va_list args;
        va_start(args, dimensions);
        int weight = 1;
        int index = va_arg(args, int);
        for (int i = 1; i < dimensions; i++) {
            weight *= lengths[i - 1];
            index += va_arg(args, int) * weight;
        }
        va_end(args);
        return elements[index];
    }

    void set(T value, ...) {
        va_list args;
        va_start(args, dimensions);
        int weight = 1;
        int index = va_arg(args, int);
        for (int i = 1; i < dimensions; i++) {
            weight *= lengths[i - 1];
            index += va_arg(args, int) * weight;
        }
        va_end(args);
        elements[index] = value;
    }

    ~DArray() {
        if (lengths != nullptr)
            delete[] lengths;
        //thanks to an answer pointing out I forgot to add this part:
        if (elements != nullptr)
            delete[] elements;
    }
};

Main.cpp: Main.cpp的:

#include "stdafx.h"
#include <iostream>

DArray<int> generateRandomMatrix(int columns, int rows) {
    int x, y;
    DArray<int> matrix = DArray<int>(2, columns, rows);
    for (y = 0; y < rows; y++) {
        for (x = 0; x < columns; x++)
            matrix.set(rand(), x, y);
    }
    return matrix;
}

int main() {
    int x, y;
    DArray<int> matrix;
    do {
        matrix = generateRandomMatrix(10, 5);
        for (y = 0; y < 5; y++) {
            for (x = 0; x < 10; x++)
                printf("%d", matrix.get(x, y));
        }
        printf("\n\nPress Enter to restart...\n");
        getchar();
    } while (true);
    return 0;
}

For some reason, which for the life of me I cannot figure out, when matrix.set() is called from inside generateRandomMatrix(), the index variable has a negative value of -462266869 which is causing an index out of bounds exception. 由于某些原因,对于我的生活我无法弄清楚,当从generateRandomMatrix()内部调用matrix.set()时,索引变量的负值为-462266869,这导致索引超出范围异常。

How can index be negative if only positive parameters are passed to the function? 如果仅将正参数传递给函数,索引如何为负数?

(Here is a screenshot of the Local Variables watch-window for what it's worth: http://i.imgur.com/LfGQ8OF.png ) (以下是Local Variables观察窗口的屏幕截图,了解它的价值: http//i.imgur.com/LfGQ8OF.png

In the member function set() , 在成员函数set()

va_start(args, dimensions);

should be 应该

va_start(args, value);

generateRandomMatrix returns DArray<int> but you don't have operator = nor copy constructor. generateRandomMatrix返回DArray<int>但您没有operator =也没有复制构造函数。

In such as case the return just copy the local class but then the destructor (of the local DArray matrix) been called and delete the allocations. 在这种情况下,返回只是复制本地类,但随后调用了析构函数(本地DArray矩阵)并删除了分配。

To resolve it, You should implement copy constructor and operator =. 要解决它,您应该实现复制构造函数和operator =。 if you are using c++11 consider also move operator. 如果您使用的是c ++ 11,请考虑移动运算符。

BTW: you have memory leak since the elements array didn't deleted. 顺便说一句:你有内存泄漏,因为elements数组没有删除。

The problem has been solved and I would like to thank the 2 answers I have got. 问题已经解决了,我要感谢我得到的2个答案。 Two things had to be fixed: 必须修复两件事:

  1. First, va_start(args, value) should have been used as va_start apparently takes the last parameter that was explicitly specified as a second parameter. 首先,应该使用va_start(args,value)作为va_start显然采用显式指定为第二个参数的最后一个参数。

The new methods are: 新方法是:

T get(int index, ...) {
    va_list args;
    va_start(args, index);
    int weight = 1;
    for (int i = 1; i < dimensions; i++) {
        weight *= lengths[i - 1];
        index += va_arg(args, int) * weight;
    }
    va_end(args);
    return elements[index];
}

void set(T value, ...) {
    va_list args;
    va_start(args, value);
    int weight = 1;
    int index = va_arg(args, int);
    for (int i = 1; i < dimensions; i++) {
        weight *= lengths[i - 1];
        index += va_arg(args, int) * weight;
    }
    va_end(args);
    elements[index] = value;
}
  1. The destructor was being called, breaking the function. 正在调用析构函数,破坏了函数。 Modifying the main method and generateRandMatrix() to use DArray* instead of DArray lumped together with the first fix solved the problem! 修改main方法和generateRandMatrix()使用DArray *而不是DArray与第一个修复集中在一起解决了问题! :D :d

A big thanks to all those who spent their time on this question. 非常感谢所有花时间在这个问题上的人。

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

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