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位的回答。必须修复两件事:
- 首先,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;
}
- 正在调用析构函数,破坏函数。修改主要方法和 generateRandMatrix() 以使用 DArray* 而不是 DArray 与第一个修复程序一起解决了问题! :D
非常感谢所有花时间解决这个问题的人。
看看这段代码:
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位的回答。必须修复两件事:
- 首先,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;
}
- 正在调用析构函数,破坏函数。修改主要方法和 generateRandMatrix() 以使用 DArray* 而不是 DArray 与第一个修复程序一起解决了问题! :D
非常感谢所有花时间解决这个问题的人。