2017-08-15 233 views
0

指针如何与数组一起工作?我发现语法有点神秘,例如(16x1):指针(指针)和新/ malloc矢量(在矢量内)C++

int* a = new int[16]; 
a[16] = 33; 
cout << a[16] << endl; 

上面的例子有效。通常*需要在写入/读取值的指针前面,而不是在向量中?

的情况是多维数组,我发现下面的方式来创建(16×3)更加复杂:

int** a = (int**)new int[16]; 
for (int i = 0; i < 16; i++) 
{ 
    a[i] = (int*)new int[3]; 
} 
a[15][2] = 4; 
cout << a[15][2] << endl; 

此外,上述作品,但很难掌握语法如何与指针。该语法也适用于malloc。使用malloc有一个选项“memset”,它自动初始化多维数组(放入for循环)。新的有类似的选择吗?

+6

你分配一个16“int”元素的“数组”,然后你写入元素号17?这是超出界限,并会导致*未定义的行为*。 –

+0

“上面的例子有效” - ':s/works/invoked-undefined-behavior/g' – WhozCraig

+0

我不熟悉指针数组和'malloc',但不会出现'a [16]'越界在第一个例子中? – kim366

回答

3

通常*需要位于指针前写入/读取值,但不与矢量?

您总是需要取消引用指针以获取指向的值。下标运算符是解引用它的另一种方式。 a[b]相当于*(a+b)(除非a是带重载下标运算符的类)。


int** a = (int**)new int[16]; 

这是一个错误。您已经分配了一组int,但尝试指向第一个元素,就好像它是int*。如果你想要一个指针数组,那么你必须在new-expression中指定正确的类型(int*)。避免像这样的错误的方法是永远不会抛出返回值new。然后编译器会在你犯错的时候告诉你。

再次,上述的工作原理

行为是不确定。

使用malloc有一个选项“memset”,它自动初始化多维数组(放在for循环中)。新的有类似的选择吗?

memset也在C++标准库中,但您不需要它进行初始化。更简单的是使用值初始化。还要注意铸造的正确类型和缺乏:

int** a = new int*[16](); 
//     ^syntax for value initialization 

附:您不会取消分配您分配的内存。因此你泄漏了内存。

P.P.S将指针存储在裸指针中的动态对象是一个坏主意。最好使用像std::vector这样的RAII容器。

+0

那么a [b] [c]是什么意思? – Dole

+1

@Dole下标运算符是左关联的,因此您可以将每个转换为显式的解引用形式,从左到右逐步形式:'a [b] [c]'=='(*(a + b))[ c]'=='*(*(a + b)+ c)' – user2079303

1

这种语法的工作原理是,operator [],称为偏移运算符,与运算符*的作用相同,但将指针增加一定量。所以a[5]*(a+5)一样。

如果您想了解更多关于它的信息,我会建议您检查article about pointer,他们在那里也提到这个操作员并提供更多的技术说明。