整数数组的动态内存分配

时间:2022-01-28 13:13:47

I am trying to create an array of size 2, dynamically, using malloc. Here is my code:

我正在尝试使用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]);

When I run this code, it prints 4, 5, 8, 9, 7.

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

I am wondering how it was able to allocate more memory (5 integers) than I requested (2 integers)?

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

6 个解决方案

#1


9  

i wondering how it was able to allocate more memory than I requested.

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

It didn't. You are invoking undefined behaviour. One possible outcome* is that your program appears to "work".

它没有。您正在调用未定义的行为。一个可能的结果*是您的程序似乎“工作”。


* Arguably, the worst.

#2


3  

Like Oli said, it's undefined. It may work, it may not. But the reality is that even though it might work 99% of the time, it will, at least once, fail, and you'll get a SEGFAULT from reading or writing memory that your process isn't supposed to be using, and you'll also end up with virtually un-debugable memory leaks.

像Oli说的那样,它是未定义的。它可能有效,但可能没有。但实际情况是,即使它可能在99%的时间内都能正常工作,但它至少会失败一次,并且你会得到一个SEGFAULT来读取或写入你的进程不应该使用的内存,而你最终还会出现几乎无法调试的内存泄漏。

#3


2  

In addition to what's been suggested if I could add a few extra notes.

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

Not sure what OS you are running this on but if you are on Linux any time you're unsure if something should work or not run it through valgrind. In my case it compiled a nice report about all the errors with your code (including not freeing the malloc-ed memory).

不确定你在运行这个操作系统的操作系统,但是如果你在Linux上,你不确定某些东西是否可行,或者不通过valgrind运行它。在我的例子中,它汇编了一个关于代码中所有错误的好报告(包括不释放malloc内存)。

I got three Invalid write of size 4 for the three extra writes you do to the memory. It also notified me of the invalid memory that you are reading in the loop with Invalid read of size 4 and finally it gave me some stats on the leaks in your code:

对于你对内存执行的三次额外写入,我得到三次无效写入大小4。它还告诉我你在循环中读取的无效内存,读取大小为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

Finally, don't cast the result of malloc.

最后,不要转换malloc的结果。

#4


1  

C doesn't do bounds checking. You are stomping on memory that your program doesn't own.

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

#5


1  

When you are invoking undefined behavior, you never know what might happen. For example when I ran the program I got the following as my output:

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

4, 5, 8, 51, 1629501832

4,5,8,51,1629501832

#6


1  

The reason this appears to work is because you are incrementing your pointer to point to new spots in memory (which your program may or may not be allocated to use). I am guessing you are declaring this on the stack and that is why your undefined behavior appears to be "ok".

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

I do not think you understand the power of a pointer and the syntax you used. Remark that the following is equivalent:

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

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 ) );
}

Consider this, alternate implementation of your code to emphasize how you are pointing to new memory addresses by indexing elements outside of your array.

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

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 ) );
}

Just a quick note on your code. A malloc should typically be followed by a free -- so use it appropriately so there are no memory leaks.

只需快速了解您的代码。 malloc后面通常应该是free - 所以要适当地使用它,这样就没有内存泄漏。

I hope this helped! Feel free to correct me if I made a mistake.

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

#1


9  

i wondering how it was able to allocate more memory than I requested.

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

It didn't. You are invoking undefined behaviour. One possible outcome* is that your program appears to "work".

它没有。您正在调用未定义的行为。一个可能的结果*是您的程序似乎“工作”。


* Arguably, the worst.

#2


3  

Like Oli said, it's undefined. It may work, it may not. But the reality is that even though it might work 99% of the time, it will, at least once, fail, and you'll get a SEGFAULT from reading or writing memory that your process isn't supposed to be using, and you'll also end up with virtually un-debugable memory leaks.

像Oli说的那样,它是未定义的。它可能有效,但可能没有。但实际情况是,即使它可能在99%的时间内都能正常工作,但它至少会失败一次,并且你会得到一个SEGFAULT来读取或写入你的进程不应该使用的内存,而你最终还会出现几乎无法调试的内存泄漏。

#3


2  

In addition to what's been suggested if I could add a few extra notes.

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

Not sure what OS you are running this on but if you are on Linux any time you're unsure if something should work or not run it through valgrind. In my case it compiled a nice report about all the errors with your code (including not freeing the malloc-ed memory).

不确定你在运行这个操作系统的操作系统,但是如果你在Linux上,你不确定某些东西是否可行,或者不通过valgrind运行它。在我的例子中,它汇编了一个关于代码中所有错误的好报告(包括不释放malloc内存)。

I got three Invalid write of size 4 for the three extra writes you do to the memory. It also notified me of the invalid memory that you are reading in the loop with Invalid read of size 4 and finally it gave me some stats on the leaks in your code:

对于你对内存执行的三次额外写入,我得到三次无效写入大小4。它还告诉我你在循环中读取的无效内存,读取大小为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

Finally, don't cast the result of malloc.

最后,不要转换malloc的结果。

#4


1  

C doesn't do bounds checking. You are stomping on memory that your program doesn't own.

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

#5


1  

When you are invoking undefined behavior, you never know what might happen. For example when I ran the program I got the following as my output:

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

4, 5, 8, 51, 1629501832

4,5,8,51,1629501832

#6


1  

The reason this appears to work is because you are incrementing your pointer to point to new spots in memory (which your program may or may not be allocated to use). I am guessing you are declaring this on the stack and that is why your undefined behavior appears to be "ok".

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

I do not think you understand the power of a pointer and the syntax you used. Remark that the following is equivalent:

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

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 ) );
}

Consider this, alternate implementation of your code to emphasize how you are pointing to new memory addresses by indexing elements outside of your array.

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

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 ) );
}

Just a quick note on your code. A malloc should typically be followed by a free -- so use it appropriately so there are no memory leaks.

只需快速了解您的代码。 malloc后面通常应该是free - 所以要适当地使用它,这样就没有内存泄漏。

I hope this helped! Feel free to correct me if I made a mistake.

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