整数数组的动态内存分配

时间:2013-07-09 02:18:11

标签: c malloc

我正在尝试使用malloc动态创建一个大小为2的数组。这是我的代码:

int *d = (int*)malloc(2 * sizeof(int));
d[0] = 4;
d[1] = 5;
d[2] = 8;
d[3] = 9;
d[4] = 7;
int i;

for (i = 0; i < 5; i++)
   printf("%d \n", d[i]);

当我运行此代码时,它会打印4, 5, 8, 9, 7

我想知道它是如何能够分配比我要求的更多的内存(5个整数)(2个整数)?

6 个答案:

答案 0 :(得分:9)

  

我想知道它是如何能够分配比我要求的更多的内存。

它没有。您正在调用未定义的行为。一个可能的结果 * 是您的计划似乎&#34;工作&#34;。

<小时/> *可以说是最差的。

答案 1 :(得分:3)

就像奥利所说,它是未定义。它可能有效,但可能没有。但实际情况是,即使它可能在99%的时间内起作用,它至少会失败一次,并且你会从读取或写入内存得到SEGFAULT,而你的过程不应该是使用,你最终会得到几乎无法调试的内存泄漏。

答案 2 :(得分:2)

除了我可以添加一些额外注释之外的建议。

不确定您在运行此操作系统的操作系统,但如果您在Linux上,则无论何时您不确定某些内容是否有效,都可以通过valgrind运行。在我的例子中,它编译了一个关于代码中所有错误的好报告(包括没有释放malloc - 内存)。

我为你对内存做的三次额外写入有三个Invalid write of size 4。它还告诉我你在Invalid read of size 4循环中读取的无效内存,最后它给了我一些关于代码泄漏的统计信息:

HEAP SUMMARY:
    in use at exit: 8 bytes in 1 blocks
  total heap usage: 1 allocs, 0 frees, 8 bytes allocated

LEAK SUMMARY:
   definitely lost: 8 bytes in 1 blocks

最后,don't cast the result of malloc.

答案 3 :(得分:1)

C不进行边界检查。你正在踩着你的程序不拥有的内存。

答案 4 :(得分:1)

当您调用未定义的行为时,您永远不知道会发生什么。例如,当我运行程序时,我得到以下作为输出:

4,5,8,51,1629501832

答案 5 :(得分:1)

这似乎起作用的原因是因为您正在递增指针以指向内存中的新位置(您的程序可能会或可能不会被分配使用)。我猜你在堆栈上声明这个,这就是为什么你的未定义行为似乎是“ok”。

我认为您不了解指针的功能和您使用的语法。注意以下内容是等效的:

int arr[ 2 ] = { 1, 2 };
int *pi = &arr;

// The following output is equivalent to...
for ( int i = 0; i < 2; i++ ) {
  printf( "arr[i] = %d.\n", arr[ i ] );
}

// this.
for ( int i = 0; i < 2; i++ ) {
  printf( "*(p + i) = %d.\n", *( p + i ) );
}

考虑这个,代码的替代实现,通过索引数组之外的元素来强调如何指向新的内存地址。

int *d = ( int * )malloc( 2 * sizeof( int ) );

*( d + 0 ) = 4; // Observe you are accessing the memory location d points to.
*( d + 1 ) = 5; // Observe you are accessing the memory location d + 4 bytes (or 8 if 64-bit) points to...
*( d + 2 ) = 8; // ...
*( d + 3 ) = 9; // ...
*( d + 4 ) = 7; // Observe you are assigning a value to the memory location of d + 24 bytes (or 48 bytes if 64-bit).

for ( int i = 0; i < 5; i++) {
   printf( "%d \n", *( d + i ) );
}

快速记下您的代码。 malloc后面通常应该是free - 所以要适当使用它,这样就不会有内存泄漏。

我希望这有帮助!如果我犯了错误,请随意纠正我。