如何使用new声明二维数组?
就像,对于"普通"数组,我会:
int* ary = new int[Size]
Run Code Online (Sandbox Code Playgroud)
但
int** ary = new int[sizeY][sizeX]
Run Code Online (Sandbox Code Playgroud)
a)不工作/编译和b)没有完成什么:
int ary[sizeY][sizeX]
Run Code Online (Sandbox Code Playgroud)
确实.
我首先要说的是,使用智能指针,你永远不必担心这一点.
以下代码有什么问题?
Foo * p = new Foo;
// (use p)
delete p;
p = NULL;
Run Code Online (Sandbox Code Playgroud)
这是由另一个问题的回答和评论引发的.Neil Butterworth的一条评论产生了一些赞成:
在删除后将指针设置为NULL不是C++中的通用优良做法.有时候它是一件好事,有时它是毫无意义的,可以隐藏错误.
有很多情况下它无济于事.但根据我的经验,它不会伤害.有人开导我.
这个问题的目的是提供一个关于如何在C中动态正确分配多维数组的参考.这是一个经常被误解的主题,即使在一些C编程书籍中也很难解释.因此,即使是经验丰富的C程序员也很难做到正确.
我从编程教师/书籍/教程中了解到,动态分配多维数组的正确方法是使用指针指针.
然而,SO上的几个高代表用户现在告诉我这是错误和不好的做法.他们说指针到指针不是数组,我实际上并没有分配数组,而且我的代码不必要地慢.
这就是我教我分配多维数组的方法:
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
int** arr_alloc (size_t x, size_t y)
{
int** pp = malloc(sizeof(*pp) * x);
assert(pp != NULL);
for(size_t i=0; i<x; i++)
{
pp[i] = malloc(sizeof(**pp) * y);
assert(pp[i] != NULL);
}
return pp;
}
int** arr_fill (int** pp, size_t x, size_t y)
{
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
pp[i][j] = (int)j + 1;
}
}
return pp;
}
void arr_print (int** pp, size_t x, size_t y) …Run Code Online (Sandbox Code Playgroud) c arrays dynamic-arrays dynamic-allocation variable-length-array
在C,这是非常清楚,使指向一个指向一个过去的数组的最后一个元素,并在指针算术使用它,只要你不取消对它的引用:
int a[5], *p = a+5, diff = p-a; // Well-defined
Run Code Online (Sandbox Code Playgroud)
但是,这些是UB:
p = a+6;
int b = *(a+5), diff = p-a; // Dereferencing and pointer arithmetic
Run Code Online (Sandbox Code Playgroud)
现在我有一个问题:这是否适用于动态分配的内存?假设我只是在指针算术中使用指向一个过去的指针,而不取消引用它,并且malloc()成功.
int *a = malloc(5 * sizeof(*a));
assert(a != NULL, "Memory allocation failed");
// Question:
int *p = a+5;
int diff = p-a; // Use in pointer arithmetic?
Run Code Online (Sandbox Code Playgroud) 如下代码:
int size = myGetSize();
std::string* foo;
foo = new std::string[size];
//...
// using the table
//...
delete[] foo;
Run Code Online (Sandbox Code Playgroud)
我听说在某些情况下这样的使用(不是这个代码,但是整个动态分配)可能是不安全的,并且只能用于RAII.为什么?
是std::array<int,10>(没有我自己使用new)保证在堆栈中分配,而不是由C++ - Standard分配?
要清楚,我不是故意的new std::array<int, 10>.我主要想知道,如果允许标准库new在其实现中使用.
为什么不能以这种方式获得缓冲区的长度.
AType * pArr = new AType[nVariable];
Run Code Online (Sandbox Code Playgroud)
取消分配相同的数组时
delete [] pArr;
Run Code Online (Sandbox Code Playgroud)
运行时必须知道释放多少.在删除数组之前是否有任何方法可以访问该长度.如果不是,为什么没有提供这样的API来获取长度?
我用的是什么意思new auto?考虑一下表达式:
new auto(5)
Run Code Online (Sandbox Code Playgroud)
动态分配对象的类型是什么?它返回的指针的类型是什么?
因错误而退出程序时,我应该释放所有的mallocated内存吗?
something = (char**) malloc (x * sizeof(char*));
for (i = 0; i < x; i++)
something[i] = (char*) malloc (y + 1);
...
if (anything == NULL) {
printf("Your input is wrong!");
// should I free memory of every mallocated entity now?
exit(1);
}
else {
// work with mallocated entities
...
free(something); // it must be here
system("pause);
}
Run Code Online (Sandbox Code Playgroud) 这似乎是一个非常基本的问题,但它一直在我脑海中:
当我们分配一个局部变量时,它会进入堆栈.类似地,动态分配会导致变量进入堆.现在,我的问题是,这个变量实际上是在堆栈还是堆上,或者我们只是堆栈和堆中的引用.
例如,
假设我声明了一个变量int i.现在这i是在堆栈上分配的.那么,当我打印地址时i,这将是堆栈中的一个位置?堆的问题也一样.
c memory-management heap-memory stack-memory dynamic-allocation
c++ ×6
c ×4
arrays ×3
malloc ×2
bounds ×1
c++11 ×1
free ×1
heap-memory ×1
new-operator ×1
null ×1
pointers ×1
size ×1
stack ×1
stack-memory ×1