C

C,c,arrays,variable-length-array,C,Arrays,Variable Length Array,如果C中的数组大小是固定的,那么这段代码是如何正常工作的呢? 这个代码是有效的,但是我的老师说我用了错误的方法 int main() { int n,element,i; printf("Enter the size of Array : "); scanf("%d",&n); int a[n]; for(i=0;i<n;i++){ printf("Enter %d no element : ",i+1);

如果C中的数组大小是固定的,那么这段代码是如何正常工作的呢? 这个代码是有效的,但是我的老师说我用了错误的方法

int main()
{
    int n,element,i;
    printf("Enter the size of Array : ");
    scanf("%d",&n);
    int a[n];

    for(i=0;i<n;i++){
        printf("Enter  %d no element : ",i+1);
        scanf("%d",&a[i]);
    }

    printf("Enter the new element to be inserted at the End: ");
    scanf("%d",&element);

    n=n+1;
    a[n-1]=element;

    for(i=0;i<n;i++){
        printf("%d\t",a[i]);
    }
}
intmain()
{
int n,元素,i;
printf(“输入数组的大小:”);
scanf(“%d”和“&n”);
int a[n];

对于(i=0;i它不起作用。至少不可靠。这是一种未定义的行为,因为您正在访问阵列之外的内存。如果您不在阵列之外很远的地方,它通常会起作用,但这样做是非常危险的,并且您处理它的方式在任何情况下都是不可接受的

如果需要更改大小,请使用如下动态分配:

int *a = malloc(n*sizeof(*a));
if (!a) { /* Handle error */ }
然后:

n=n+1;
// Using a void pointer, because this pointer should not be used for 
// dereferencing
void *tmp = realloc(a, n*sizeof(*a));
if (!tmp) { /* Handle error */ }
a = tmp;

事实上,我更喜欢动态分配,而不是任何时候都使用VLA:s。事实上,他们删除了在moderrn C标准中对编译器支持它们的要求,这很好地表明使用它们是一个坏主意。而且,由于对它们的支持不再是强制性的,使用它们可能会在将来破坏您的代码。

什么如果我想将分配的内存位置释放到您注入的最后一个变量

1-它会被释放吗


在一个较小的层面上,它会对你有用,从一个更广阔的角度思考,你必须小心地使用每一个细节,这不是一个好的实践(从这个角度思考)。相反,这将建议您使用动态内存分配来提高代码质量。

在高铁上,您购买了一张车票,很幸运还有一张空车票 网站在你旁边,然后你把你的包放在上面。这并不意味着你拥有那个网站,只是因为现在没有其他人拥有这个网站

事实上,编程时,你并不声明你拥有这个内存,你可以修复它,然后做一切正常的事情,直到某个程序声明拥有这个内存。就像另一个拥有这个内存的程序一样,高铁售票员站在你旁边,出示他的车票

int a[n];//mean you own n size of int so you  own a[0]~a[n-1] this n mean in this line your n value,if next line n increase a's size will not increase
//------------------------------------------------------------
//Not legal because n is not const
int a[n];
//------------------------------------------------------------
//In fact this is legal
int *a;
a=(int*)malloc(sizeof(int)*n);//will alloc n of int for you
    //Do something you want
    //
free(a);//release your memory alloc
//------------------------------------------------------------
//Or just give a big enough for a like
int a[1000];
//------------------------------------------------------------

但是数组
a
的大小是固定的,它的大小始终是您在修改
n
之前为
n
最初输入的元素数。我们无法帮助您“固定”如果我们不知道它出了什么问题,这是很重要的。也许你应该请你的老师澄清一下?还要知道C没有任何边界检查。如果你超出了数组的边界,那么你将有未定义的行为。你的老师是对的。代码有未定义的行为,因为在创建数组之后,代码会写过去它的结束。如果它似乎对你有用的话,你只是碰巧运气好,或者运气不好。它不能保证正确工作(不管你如何定义“正确”)如果您将
i
设置为与
element
不同的值,并在
a[n-1]=element;
之后立即输出
i
会发生什么幸运的是,当你添加一个元素时,程序没有崩溃。添加十几个元素,你的程序更有可能崩溃。为什么你得到(un)幸运?假设您为
n
输入了
5
。编译器可以自由地保留一些与当时要维护的对齐方式一致的最小存储大小。因此编译器很可能已经为数组保留了
8、16、32、
全部元素,但您不能有效地使用超过
5
。没有保证请注意,下一次请求存储时,编译器不会分配
&a[6]的地址
在本例中使用。因此,底线是,通过超出数组边界进行写入,您调用了未定义的行为,代码的定义执行到此结束。事实上,他们取消了在moderrn C标准中支持编译器的要求,这很好地说明了标准化中的政治process@M.M 也许吧,但无法检查错误这一事实是一个主要缺点。您也不能在
inta[1000000];
中检查错误;您可以在数组之前对
n
进行一些用户验证definition@M.M是的,但是你永远不会写
inta[1000000]
如果您对堆栈有任何了解。此外,如果您需要检查可用的堆栈空间,那么首先您可能是错的。那么您希望在
int a[n]中检查哪些错误;
呢?这个答案真的不清楚。首先,这个问题并没有问任何关于释放内存的问题。也没有什么是“注入”的此处的任意位置(在编程上下文中通常指“注入”).@hyde对这个问题的回答在之前的回答中已经解释得很好了,我认为上面的解释足以理解问题和解决方案。我在这里以另一种方式解释这个问题,在内存利用率和提出这个问题的开发人员的背景下,他仍然处于学习阶段,所以我们需要指导他使用更好的c编码实践。