所以我的代码是这样的:
trigger
我的问题是,我被告知这是一种分配内存的错误方法,我应该使用malloc。我应该使用用户的维度创建一个动态数组。
编辑:程序的其余部分:
jQuery("select").change(function (e) {
var str = "";
str = jQuery(this).find("option:selected").text();
jQuery(".labelChanged").text(str);
}).trigger('change')
e.preventDefault()
答案 0 :(得分:6)
取决于您如何定义"更正"。这是C99以来的合法C.
但问题是,如果b
和malloc
太大,则数组将溢出调用堆栈。如果这是一种可能的情况,您应该更喜欢double (*array)[b] = malloc(sizeof(double[a][b]));
。与堆相比,调用堆栈通常被分配得相当小。所以这可能是建议的来源。
请注意,您仍然可以使用动态分配的数组来享受数组下标表示法:
a[i][j]
数组在一个连续的块中,VLA指针将导致test_abc.R
引用正确的元素。
答案 1 :(得分:5)
不,这是完全正确且有效的方式,只要您使用支持Variable-length array的编译器版本/环境。
这是C99
上的强制性功能,但在C11
上再次可选。
使用VLA和"指针和内存分配器功能组合"之间的主要区别是
答案 2 :(得分:4)
C编译器可以将其作为有效代码处理,尽管C11 standard made VLA support optional。
主要问题是实际上你无法检查分配是否成功,特别是当大小未知时。这也是malloc/calloc
:
double (*array1)[b] = malloc(a * sizeof(*array1));
if (!array1) {
// handle allocation failure
}
答案 3 :(得分:2)
scanf("%d %d", &a, &b);
double array1[a][b];
这在C99标准中是有效的,尽管您希望首先对输入进行一些完整性检查(即,确保两个输入都被实际读取,确保它们都不是负数,请确保它们是&#39 ;在合理的范围内,等等)。
array1
是一个可变长度数组(VLA),它首先在C99中引入。从C2011开始,它们已经成为可选项,但我认为几乎所有托管的实现仍然支持它们。要确保检查__STDC_NO_VLA__
宏 - 如果已定义,则实现不支持VLA。
size_t a, b;
if ( scanf( "%zu %zu", &a, &b ) < 2 )
// bail out with an error message
#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L && !defined( __STDC_NO_VLA__ )
/**
* This implementation supports VLAs. We need to do an additional
* sanity check on a and b to make sure we don't allocate an
* object too large for the stack (even though VLAs
* don't have to be allocated on the stack, that's how many
* implementations choose to do it).
*/
if ( a > SOME_MAX_LIMIT || b > SOME_MAX_LIMIT )
// bail out with an error
double array1[a][b];
#else
/**
* This implementation does not support VLAs, so we'll have to use
* dynamic memory allocation. Note that memory allocated this way
* is *not* contiguous - rows are not adjacent, so the object immediately
* following array1[0][b-1] is not array1[1][0]. If that matters,
* then this won't work.
*/
double **array1 = malloc( sizeof *array1 * a );
if ( array1 )
{
size_t i;
for ( i = 0; i < a; i++ )
{
array1[i] = malloc( sizeof *array1[i] * b );
if ( !array1[i] )
break;
}
if ( i < a ) // memory allocation failure, clean up any previously allocated memory
{
while ( i-- )
free( array1[i] );
free( array1 );
// bail out with an error here
}
}
else
// memory allocation failed, bail with an error
#endif
此时,无论我们分配哪种方式,您的代码都可以引用array1[i][j]
。但是,您需要在函数末尾添加它:
#if !defined( __STDC_VERSION__ ) || __STDC_VERSION__ < 199901L || defined( __STDC_NO_VLA__ )
for ( size_t i = 0; i < a; i++ )
free( array1[i] );
free( array1 );
#endif
如果我们必须使用malloc
,我们就可以自行清理。
VLA与其他auto
(本地)数组非常相似 - 当您退出函数时,它们的内存将被释放,因此您无法返回指向它们的指针并使指针为函数退出后有效。
由于它们的大小在运行时尚未确定,因此您无法在文件范围内使用它们(在任何函数之外),您不能将它们声明为static
,并且它们不能是struct
或union
类型的成员。
您可以将VLA与动态内存分配结合使用:
size_t a, b;
if ( scanf( "%zu %zu", &a, &b ) < 2 )
// bail out with an error
double (*array1)[b] = malloc( sizeof *array1 * a );
您将获得一个动态分配的2D阵列,其中包含 连续的用户指定维度,并且您只受堆大小限制,而不是堆栈大小,因此您可以分配大以这种方式对象。