c ++:本地数组定义与malloc调用

时间:2022-11-27 16:59:50

What is the difference between this:

这有什么区别:

somefunction() {  
    ...  
    char *output;   
    output = (char *) malloc((len * 2) + 1);  
    ...  
}  

and this:

somefunction() {  
    ...  
    char output[(len * 2) + 1];  
    ...  
}  

When is one more appropriate than the other?

什么时候比另一个更合适?

thanks all for your answers. here is a summary:

谢谢大家的回答。这是一个总结:

  1. ex. 1 is heap allocation
  2. 恩。 1是堆分配

  3. ex. 2 is stack allocation
  4. 恩。 2是堆栈分配

  5. there is a size limitation on the stack, use it for smaller allocations
  6. 堆栈有一个大小限制,用于较小的分配

  7. you have to free heap allocation, or it will leak
  8. 你必须释放堆分配,否则它会泄漏

  9. the stack allocation is not accessible once the function exits
  10. 一旦函数退出,就无法访​​问堆栈分配

  11. the heap allocation is accessible until you free it (or the app ends)
  12. 在您释放堆分配(或应用程序结束)之前,可以访问堆分配

  13. VLA's are not part of standard C++
  14. VLA不是标准C ++的一部分

corrections welcome.

here is some explanation of the difference between heap vs stack:
What and where are the stack and heap?

这里有一些关于堆与堆栈之间差异的解释:堆栈和堆的内容和位置是什么?

5 个解决方案

#1


5  

Use locals when you only have a small amount of data, and you are not going to use the data outside the scope of the function you've declared it in. If you're going to pass the data around, use malloc.

当您只有少量数据时使用本地数据,并且您不会使用您声明它所在函数范围之外的数据。如果您要传递数据,请使用malloc。

Local variables are held on the stack, which is much more size limited than the heap, where arrays allocated with malloc go. I usually go for anything > 16 bytes being put on the heap, but you have a bit more flexibility than that. Just don't be allocating locals in the kb/mb size range - they belong on the heap.

局部变量保存在堆栈上,其大小比堆大得多,其中使用malloc分配的数组。我通常会在堆上放置> 16个字节的任何内容,但是你有更多的灵活性。只是不要在kb / mb大小范围内分配本地 - 它们属于堆。

#2


6  

The first allocates memory on the heap. You have to remember to free the memory, or it will leak. This is appropriate if the memory needs to used outside the function, or if you need to allocate a huge amount of memory.

第一个在堆上分配内存。你必须记住释放内存,否则它会泄漏。如果内存需要在函数外部使用,或者需要分配大量内存,这是合适的。

The second allocates memory on the stack. It will be reclaimed automatically when the function returns. This is the most convenient if you don't need to return the memory to your caller.

第二个在堆栈上分配内存。当函数返回时,它将自动回收。如果您不需要将内存返回给调用者,这是最方便的。

#3


5  

The first example allocates a block of storage from the heap. The second one allocates storage from the stack. The difference becomes visible when you return output from somefunction(). The dynamically allocated storage is still available for your use, but the stack-based storage in the second example is, um, nowhere. You can still write into this storage and read it for awhile, until the next time you call a function, at which time the storage will get overwritten randomly with return addresses, arguments, and such.

第一个示例从堆中分配一个存储块。第二个从堆栈中分配存储。从somefunction()返回输出时,差异变得可见。动态分配的存储仍然可供您使用,但第二个示例中基于堆栈的存储是,嗯,无处可去。你仍然可以写入这个存储并读取它一段时间,直到你下次调用一个函数,此时存储将被随机覆盖返回地址,参数等。

There's a lot of other weird stuff going on with the code in this question too. First off, it this is a c++ program, you'd want to use new instead of malloc() so you'd say

这个问题中的代码还有很多其他奇怪的东西。首先,这是一个c ++程序,你想要使用new而不是malloc(),所以你会说

output = new char[len+1];

And what's with the len*2 + 1 anyway? Maybe this is something special in your code, but I'm guessing you want to allocate unicode characters or multibyte characters. If it's unicode, the null termination takes two bytes as well as each character does, and char is the wrong type, being 8 bit bytes in most compilers. If it's multibyte, then hey, all bets are off.

而len * 2 + 1又是什么?也许这是你的代码中的特殊内容,但我猜你要分配unicode字符或多字节字符。如果它是unicode,则null终止需要两个字节以及每个字符,并且char是错误的类型,在大多数编译器中是8位字节。如果它是多字节的,那么嘿,所有的赌注都关闭了。

#4


3  

First some terminology:

首先是一些术语:

  • The first sample is called heap allocation.
  • 第一个样本称为堆分配。

  • The second sample is called stack allocation.
  • 第二个样本称为堆栈分配。

The general rule is: allocate on the stack, unless:

一般规则是:在堆栈上分配,除非:

  1. The required size of the array is unknown at compile time.
  2. 编译时所需的数组大小未知。

  3. The required size exceeds 10% of the total stack size. The default stack size on Windows and Linux is usually 1 or 2 MB. So your local array should not exceed 100,000 bytes.
  4. 所需的大小超过总堆栈大小的10%。 Windows和Linux上的默认堆栈大小通常为1或2 MB。因此,本地阵列不应超过100,000个字节。

#5


1  

You tagged your question with both C++ and C, but the second solution is not allowed in C++. Variable length arrays are only allowed in C(99).

您使用C ++和C标记了您的问题,但在C ++中不允许使用第二个解决方案。可变长度数组仅允许在C(99)中。

If you were to assume 'len' is a constant, both will work.

如果你假设'len'是常数,那么两者都可以。

malloc() (and C++'s 'new') allocate the memory on the heap, which means you have to free() (or if you allocated with 'new', 'delete') the buffer, or the memory will never be reclaimed (leak).

malloc()(和C ++的'new')在堆上分配内存,这意味着你必须free()(或者如果你用'new','delete'分配)缓冲区,或者内存永远不会被回收(泄漏)。

The latter allocates the array on the stack, and will be gone when it goes out of scope. This means that you can't return pointers to the buffer outside the scope it's allocated in.

后者在堆栈上分配数组,当它超出范围时将消失。这意味着您不能将指针返回到分配范围之外的缓冲区。

The former is useful when you want to pass the block of memory around (but in C++, it's best managed with an RAII class, not manually), while the latter is best for small, fixed-size arrays that only need to exist in one scope.

当你想要传递内存块时,前者很有用(但在C ++中,最好用RAII类来管理,而不是手动),而后者最适合只需要存在于一个中的小型固定大小的数组范围。

Lastly, you can mark the otherwise stack-allocated array with 'static' to take it off the stack and into a global data section:

最后,您可以使用'static'标记堆栈分配的数组,以将其从堆栈中取出并进入全局数据部分:

static char output[(len * 2) + 1];

This enables you to return pointers to the buffer outside of its scope, however, all calls to such a function will refer to the same piece of global data, so don't use it if you need a unique block of memory every time.

这使您可以返回指向其作用域之外的缓冲区的指针,但是,对此类函数的所有调用都将引用相同的全局数据,因此如果每次都需要一个唯一的内存块,请不要使用它。

Lastly, don't use malloc in C++ unless you have a really good reason (i.e, realloc). Use 'new' instead, and the accompanying 'delete'.

最后,除非你有充分的理由(即realloc),否则不要在C ++中使用malloc。改为使用'new',随附'delete'。

#1


5  

Use locals when you only have a small amount of data, and you are not going to use the data outside the scope of the function you've declared it in. If you're going to pass the data around, use malloc.

当您只有少量数据时使用本地数据,并且您不会使用您声明它所在函数范围之外的数据。如果您要传递数据,请使用malloc。

Local variables are held on the stack, which is much more size limited than the heap, where arrays allocated with malloc go. I usually go for anything > 16 bytes being put on the heap, but you have a bit more flexibility than that. Just don't be allocating locals in the kb/mb size range - they belong on the heap.

局部变量保存在堆栈上,其大小比堆大得多,其中使用malloc分配的数组。我通常会在堆上放置> 16个字节的任何内容,但是你有更多的灵活性。只是不要在kb / mb大小范围内分配本地 - 它们属于堆。

#2


6  

The first allocates memory on the heap. You have to remember to free the memory, or it will leak. This is appropriate if the memory needs to used outside the function, or if you need to allocate a huge amount of memory.

第一个在堆上分配内存。你必须记住释放内存,否则它会泄漏。如果内存需要在函数外部使用,或者需要分配大量内存,这是合适的。

The second allocates memory on the stack. It will be reclaimed automatically when the function returns. This is the most convenient if you don't need to return the memory to your caller.

第二个在堆栈上分配内存。当函数返回时,它将自动回收。如果您不需要将内存返回给调用者,这是最方便的。

#3


5  

The first example allocates a block of storage from the heap. The second one allocates storage from the stack. The difference becomes visible when you return output from somefunction(). The dynamically allocated storage is still available for your use, but the stack-based storage in the second example is, um, nowhere. You can still write into this storage and read it for awhile, until the next time you call a function, at which time the storage will get overwritten randomly with return addresses, arguments, and such.

第一个示例从堆中分配一个存储块。第二个从堆栈中分配存储。从somefunction()返回输出时,差异变得可见。动态分配的存储仍然可供您使用,但第二个示例中基于堆栈的存储是,嗯,无处可去。你仍然可以写入这个存储并读取它一段时间,直到你下次调用一个函数,此时存储将被随机覆盖返回地址,参数等。

There's a lot of other weird stuff going on with the code in this question too. First off, it this is a c++ program, you'd want to use new instead of malloc() so you'd say

这个问题中的代码还有很多其他奇怪的东西。首先,这是一个c ++程序,你想要使用new而不是malloc(),所以你会说

output = new char[len+1];

And what's with the len*2 + 1 anyway? Maybe this is something special in your code, but I'm guessing you want to allocate unicode characters or multibyte characters. If it's unicode, the null termination takes two bytes as well as each character does, and char is the wrong type, being 8 bit bytes in most compilers. If it's multibyte, then hey, all bets are off.

而len * 2 + 1又是什么?也许这是你的代码中的特殊内容,但我猜你要分配unicode字符或多字节字符。如果它是unicode,则null终止需要两个字节以及每个字符,并且char是错误的类型,在大多数编译器中是8位字节。如果它是多字节的,那么嘿,所有的赌注都关闭了。

#4


3  

First some terminology:

首先是一些术语:

  • The first sample is called heap allocation.
  • 第一个样本称为堆分配。

  • The second sample is called stack allocation.
  • 第二个样本称为堆栈分配。

The general rule is: allocate on the stack, unless:

一般规则是:在堆栈上分配,除非:

  1. The required size of the array is unknown at compile time.
  2. 编译时所需的数组大小未知。

  3. The required size exceeds 10% of the total stack size. The default stack size on Windows and Linux is usually 1 or 2 MB. So your local array should not exceed 100,000 bytes.
  4. 所需的大小超过总堆栈大小的10%。 Windows和Linux上的默认堆栈大小通常为1或2 MB。因此,本地阵列不应超过100,000个字节。

#5


1  

You tagged your question with both C++ and C, but the second solution is not allowed in C++. Variable length arrays are only allowed in C(99).

您使用C ++和C标记了您的问题,但在C ++中不允许使用第二个解决方案。可变长度数组仅允许在C(99)中。

If you were to assume 'len' is a constant, both will work.

如果你假设'len'是常数,那么两者都可以。

malloc() (and C++'s 'new') allocate the memory on the heap, which means you have to free() (or if you allocated with 'new', 'delete') the buffer, or the memory will never be reclaimed (leak).

malloc()(和C ++的'new')在堆上分配内存,这意味着你必须free()(或者如果你用'new','delete'分配)缓冲区,或者内存永远不会被回收(泄漏)。

The latter allocates the array on the stack, and will be gone when it goes out of scope. This means that you can't return pointers to the buffer outside the scope it's allocated in.

后者在堆栈上分配数组,当它超出范围时将消失。这意味着您不能将指针返回到分配范围之外的缓冲区。

The former is useful when you want to pass the block of memory around (but in C++, it's best managed with an RAII class, not manually), while the latter is best for small, fixed-size arrays that only need to exist in one scope.

当你想要传递内存块时,前者很有用(但在C ++中,最好用RAII类来管理,而不是手动),而后者最适合只需要存在于一个中的小型固定大小的数组范围。

Lastly, you can mark the otherwise stack-allocated array with 'static' to take it off the stack and into a global data section:

最后,您可以使用'static'标记堆栈分配的数组,以将其从堆栈中取出并进入全局数据部分:

static char output[(len * 2) + 1];

This enables you to return pointers to the buffer outside of its scope, however, all calls to such a function will refer to the same piece of global data, so don't use it if you need a unique block of memory every time.

这使您可以返回指向其作用域之外的缓冲区的指针,但是,对此类函数的所有调用都将引用相同的全局数据,因此如果每次都需要一个唯一的内存块,请不要使用它。

Lastly, don't use malloc in C++ unless you have a really good reason (i.e, realloc). Use 'new' instead, and the accompanying 'delete'.

最后,除非你有充分的理由(即realloc),否则不要在C ++中使用malloc。改为使用'new',随附'delete'。