C++可变参数问题

C++ variadic parameters issue

看看这段代码:

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:

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

出于某种原因,我无法弄清楚,当从 generateRandomMatrix() 内部调用 matrix.set() 时,索引变量的负值为 -462266869,这会导致索引越界异常。

如果只向函数传递正参数,索引怎么可能是负数?

(这是局部变量监视的屏幕截图-window 其价值:http://i.imgur.com/LfGQ8OF.png

generateRandomMatrix returns DArray<int> 但你没有 operator = 也没有复制构造函数。

在这种情况下,return 只是复制本地 class,然后调用析构函数(本地 DArray 矩阵的)并删除分配。

要解决它,您应该实现复制构造函数和运算符=。如果您使用的是 c++11,还请考虑移动运算符。

顺便说一句:由于 elements 数组未删除,您有内存泄漏。

在成员函数set(),

va_start(args, dimensions);

应该是

va_start(args, value);

问题已经解决,感谢2位的回答。必须修复两件事:

  1. 首先,va_start(args, value) 应该被使用,因为 va_start 显然采用了明确指定为第二个参数的最后一个参数。

新方法是:

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. 正在调用析构函数,破坏函数。修改主要方法和 generateRandMatrix() 以使用 DArray* 而不是 DArray 与第一个修复程序一起解决了问题! :D

非常感谢所有花时间解决这个问题的人。