C 中的数组变异
Array Mutation in C
如果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]);
}
}
它不起作用。至少不可靠。这是未定义的行为,因为您正在访问数组外的内存。如果你不在数组之外走得太远,它通常会起作用,但这样做是非常危险的,而且你处理它的方式在任何情况下都是不可接受的。
如果你需要改变大小,那么使用这样的动态分配:
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。他们取消了编译器在现代 C 标准中支持它们的要求这一事实很好地表明使用它们是一个坏主意。由于对它们的支持不再是强制性的,因此将来使用它们可能会破坏您的代码。
如果我想释放分配给您注入的最后一个变量的内存位置怎么办。
1 - 它会被释放吗?
在较小的层面上,它会为你工作,从更广阔的角度思考,你必须小心使用每一位,这不是一个好的做法(从这个角度思考)。相反,这将建议您使用动态内存分配将提高您的代码质量。
在高铁上买了票,还好还有一个空位
网站在你旁边,然后你把你的包放在 it.It 并不意味着你拥有那个网站,只是因为现在没有另一个人拥有这个网站。
事实上编程,你并没有声明你拥有这个内存,你可以修复它并做一切正常,直到某个程序声明拥有 memory.Just 就像另一个拥有站在旁边的高铁售票员一样你并出示他的票。
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];
//------------------------------------------------------------
如果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]);
}
}
它不起作用。至少不可靠。这是未定义的行为,因为您正在访问数组外的内存。如果你不在数组之外走得太远,它通常会起作用,但这样做是非常危险的,而且你处理它的方式在任何情况下都是不可接受的。
如果你需要改变大小,那么使用这样的动态分配:
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。他们取消了编译器在现代 C 标准中支持它们的要求这一事实很好地表明使用它们是一个坏主意。由于对它们的支持不再是强制性的,因此将来使用它们可能会破坏您的代码。
如果我想释放分配给您注入的最后一个变量的内存位置怎么办。
1 - 它会被释放吗?
在较小的层面上,它会为你工作,从更广阔的角度思考,你必须小心使用每一位,这不是一个好的做法(从这个角度思考)。相反,这将建议您使用动态内存分配将提高您的代码质量。
在高铁上买了票,还好还有一个空位 网站在你旁边,然后你把你的包放在 it.It 并不意味着你拥有那个网站,只是因为现在没有另一个人拥有这个网站。
事实上编程,你并没有声明你拥有这个内存,你可以修复它并做一切正常,直到某个程序声明拥有 memory.Just 就像另一个拥有站在旁边的高铁售票员一样你并出示他的票。
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];
//------------------------------------------------------------