英文:
Why isn't my loop working correctly in c?
问题
这是我的代码。首先应该扫描2个数字m和n。然后扫描一个包含n个数字的数组x[n]。第二行中扫描的数字数量应该是n。但它不正常工作。
#include <stdio.h>
int main()
{
int m = 0;
int n = 0;
int x[n];
scanf("%d", &m);
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &x[i]);
}
}
它只扫描了1个数字然后退出了循环。应该从0到n-1扫描(i)的值。
英文:
This is my code. It is supposed to first of all scan 2 number m and n. Then scan an array of numbers that is x[n]. Number of scanned numbers in second line should be n. But it doesn't work correctly.
#include <stdio.h>
int main()
{
int m = 0;
int n = 0;
int x[n];
scanf("%d", &m);
scanf("%d", &n);
for(int i = 0 ;i < n;i++)
{
scanf("%d", &x[i]);
}
}
It just scans 1 number and breaks out of the loop. We should have (i)s from 0 until n-1;
答案1
得分: 3
This attempts to declare a Variable Length Array of size zero, which already is undefined behaviour. And even if that (having a VLA with room for zero elements) were somehow possible, scanf("%d", &x[i]);
would also be undefined behavior.
英文:
int n = 0;
int x[n];
This attempts to declare a Variable Length Array of size zero, which already is undefined behaviour.
And even if that (having a VLA with room for zero elements) were somehow possible,
scanf("%d", &x[i]);
...would also be undefined behavior.
答案2
得分: 1
以下是代码段的翻译部分:
"Let me try to explain the behavior of the code considering x86_64
architecture and gcc7.5x
compiler."
"This answer and this answer to the questions provides the direction of stack growth on different architectures for x86
it is downward, meaning the stack will grow from high memory to low memory address (0xFF --> 0x00)"
"If we slightly modify your code to print the addresses and values of the variable during runtime as shown:"
#include <stdio.h>;
int main()
{
int m = 0;
int n = 0;
int x[n];
printf("Size of int: %d\n", sizeof(int));
printf("Address of\nm: %p\nn: %p\nx: %p\n", &m, &n, &x);
printf("Enter a value of m: ");
scanf("%d", &m);
printf("Enter a value of n: ");
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d", &x[i]);
printf("Addr: %p\n", &x[i]);
}
for(int j = 0; j < n; j++)
{
printf("x[%d]: %d\n", x[j]);
}
printf("m: %d n: %d\n", m, n);
}
"After compiling and running the above code on x86
, we can notice that the addresses to the local variables get assigned in decreasing order as shown below for one of the code execution session:"
Address of
m: 0x7ffdfb2b1704
n: 0x7ffdfb2b1700
x: 0x7ffdfb2b16f0
"If you notice the difference in the address of n
and x
, they are 16-Bytes
apart, ideally they should have been 4-bytes
apart on the stack."
"But as int x[n]
is declared to be an array of 0 integers, ideally it should occupy 4-bytes of memory, even though the underlying compiler and architecture mechanism is treating it as an array of 4 integers, which gets translated to 4 integers * sizeof(int) = 16-bytes
."
"Looking at further execution output of the code, we can see that the value of n
at address 0x7ffdfb2b1700
gets overwritten as the code executes further."
"Note that the code will work properly for values of n < 5
, because for the value of n = 4
, the loop will terminate at n = 3
in which case the value of n
will not get overwritten because of loop iteration as (n * sizeof(int)) ==> 3 * 4 = 12-bytes:
"
Enter a value of m: 1
Enter a value of n: 10
1
Addr: 0x7ffdfb2b16f0
2
Addr: 0x7ffdfb2b16f4
3
Addr: 0x7ffdfb2b16f8
4
Addr: 0x7ffdfb2b16fc
5
Addr: 0x7ffdfb2b1700 <--- address of variable `n` getting overwritten with a new value
x[1]: 0
x[2]: 1
x[3]: 2
x[4]: 3
x[5]: 4
m: 1 n: 5
"And this is the reason why @DevSolar answered that this will result in an undefined behavior."
"I hope I was able to provide some clarification."
英文:
Let me try to explain the behavior of the code considering x86_64
architecture and gcc7.5x
compiler.
This answer and this answer to the questions provides the direction of stack growth on different architectures for x86
it is downward, meaning the stack will grow from high memory to low memory address (0xFF --> 0x00)
If we slightly modify your code to print the addresses and values of the variable during runtime as shown:
#include <stdio.h>
int main()
{
int m = 0;
int n = 0;
int x[n];
printf("Size of int: %d\n", sizeof(int));
printf("Address of\nm: %p\nn: %p\nx: %p\n", &m, &n, &x);
printf("Enter a value of m: ");
scanf("%d", &m);
printf("Enter a value of n: ");
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d", &x[i]);
printf("Addr: %p\n", &x[i]);
}
for(int j = 0; j < n; j++)
{
printf("x[%d]: %d\n", x[j]);
}
printf("m: %d n: %d\n", m, n);
}
After compiling and running the above code on x86
, we can notice that the addresses to the local variables get assigned in decreasing order as shown below for one of the code execution session:
Address of
m: 0x7ffdfb2b1704
n: 0x7ffdfb2b1700
x: 0x7ffdfb2b16f0
If you notice the difference in the address of n
and x
, they are 16-Bytes
apart, ideally they should have been 4-bytes
apart on stack.
But as int x[n]
is declared to be an array of 0 integers ideally it should occupy 4-bytes of memory, even though the underlying compiler and architecture mechanism is treating it as an array of 4 integers, which gets translated to
4 integers * sizof(int) = 16-bytes
Looking at further execution output of the code, we can see that the value of n
at address 0x7ffdfb2b1700
gets overwritten as the code executes further.
> Note that the code will work properly for values of n < 5
, because for the value of n = 4
the loop will terminate at n = 3
in which case the value of n
will not get overwritten because of loop iteration as (n * sizeof(int)) ==> 3 * 4 = 12-bytes
:
Enter a value of m: 1
Enter a value of n: 10
1
Addr: 0x7ffdfb2b16f0
2
Addr: 0x7ffdfb2b16f4
3
Addr: 0x7ffdfb2b16f8
4
Addr: 0x7ffdfb2b16fc
5
Addr: 0x7ffdfb2b1700 <--- address of variable `n` getting overwritten with new value
x[1]: 0
x[2]: 1
x[3]: 2
x[4]: 3
x[5]: 4
m: 1 n: 5
And this is the reason why @DevSolar answered that this will result in an undefined behavior.
I hope I was able to provide some clarification.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论