这两种内存分配方法有什么区别?

时间:2015-08-18 13:37:44

标签: c pointers

以下是p[10][10]数组的内存分配方法。

//First
char** p;
int i;
p=(char**)malloc(10*sizeof(char*));
for(i=0;i<10;i++)
    p[i]=(char*)malloc(10*sizeof(char));

//Second
char** p;
int i;
p=(char**)malloc(10*sizeof(char*));
*p=(char*)malloc(100*sizeof(char));
for(i=1;i<10;i++)
    p[i]=p[0]+10*i;

两者有什么区别?

3 个答案:

答案 0 :(得分:9)

这些都不是C ++。第一个分配10 char*的数组,然后将每个数组分配给一个单独的动态分配的10 char数组。每个10的数组都是独立的,因此您无法保证p[0][9]p[1][0]之间存在差异:

  p
+------+
| p[0] |  --> [][][][][][][][][][]
+------+
| p[1] |  --> [][][][][][][][][][]
+------+
|      |  --> [][][][][][][][][][]
+------+
 ...  
+------+
| p[9] |  --> [][][][][][][][][][]
+------+

在第二种情况下,您有一个100 char的连续数组,而您的10 char*每个指向不同的段:

   0  1  2      10     20
  +--+--+--+   +--+   +--+
  |  |  |  |...|  |...|  |...    <== dynamically allocated array of 100 char
  +--+--+--+   +--+   +--+
    |         /       /
    \        /       /
  +------+------+------+
p | p[0] | p[1] | p[2] |...      <== dynamically allocated array of 10 char*
  +------+------+------+

您确实可以保证char之后p[0][9] p[1][0]char p[10][10];

虽然这些都不是真正的数组。为此,您需要:

char*

这将给出第二个块的等效行为 - 减去10 std::array<std::array<char, 10>, 10> p; 的所有额外开销和动态内存分配。在C ++中,我们更喜欢将其写为:

function ConfirmGroupDelete() {
            if (confirm('Är du säker på att du vill ta bort alla händelser i gruppen Test3?')) {
                return true;
            } else {
                return false;
            }
        }

答案 1 :(得分:4)

您正在动画片段中动态分配数组。不同之处在于,第一个代码段为Zig-zag(取决于内存空间的可用性)方式中的10个char指针中的每一个分配内存。第二个片段为10个char指针中的每一个分配连续内存。

请参阅图片以更清楚地了解

int **array1 = malloc(nrows * sizeof(int *));
    for(i = 0; i < nrows; i++)
        array1[i] = malloc(ncolumns * sizeof(int));    

enter image description here

int **array2 = malloc(nrows * sizeof(int *));
    array2[0] = malloc(nrows * ncolumns * sizeof(int));
    for(i = 1; i < nrows; i++)
        array2[i] = array2[0] + i * ncolumns; 

enter image description here

进一步阅读:How can I dynamically allocate a multidimensional array?

答案 2 :(得分:3)

在此代码段中

char** p;
int i;
p=(char**)malloc(10*sizeof(char*));
for(i=0;i<10;i++)
    p[i]=(char*)malloc(10*sizeof(char));

为类型为char *的10个指针的一维数组分配了内存:

p=(char**)malloc(10*sizeof(char*));

每个指针依次由分配的内存地址初始化,用于10个char类型元素的一维数组:

for(i=0;i<10;i++)
    p[i]=(char*)malloc(10*sizeof(char));

在此cade片段中

char** p;
int i;
p=(char**)malloc(10*sizeof(char*));
*p=(char*)malloc(100*sizeof(char));
for(i=1;i<10;i++)
    p[i]=p[0]+10*i;

首先为第一个代码片段中的10个char *类型元素的一维数组分配内存。

p=(char**)malloc(10*sizeof(char*));

然而,对于类型为char的100个元素的on-dimensional数组,只有数组的第一个元素由已分配内存的地址初始化。

*p=(char*)malloc(100*sizeof(char));

以上陈述相当于

p[0]=(char*)malloc(100*sizeof(char));

然后其他9个指针由整数表达式10*i

初始化
for(i=1;i<10;i++)
    p[i]=p[0]+10*i;

很明显,这没有意义。这9个元素的值无效,因为它们不是指向对象的指针。这是初始化的目的尚不清楚。

考虑到你可以按照以下方式为一个二维数组分配内存

char ( *p )[10] = malloc( 100 * sizeof( char ) );

这种分配的优点是你只需要一次调用函数free即可释放所有已分配的内存。而且这个指针可以用作具有参数作为两个二元数组的函数的参数。

例如

void func( char a[][10] );

您可以将此功能称为

func( p );

但是,如果p的类型为char **,则可能无法调用该函数,因为此类型与参数类型不兼容。