C 结构阵列存储器排列
填充的数组在内存中是如何排列的? filled是数组的名称,返回数组的基址…类似地&filled。但是 filled[0]给出了一些未知值,可能是地址,而googly部分为&filled[0],其中 给出值10。我搞不懂逻辑。下面是我得到的输出C 结构阵列存储器排列,c,C,填充的数组在内存中是如何排列的? filled是数组的名称,返回数组的基址…类似地&filled。但是 filled[0]给出了一些未知值,可能是地址,而googly部分为&filled[0],其中 给出值10。我搞不懂逻辑。下面是我得到的输出 struct abc filled[]={{"aa",10},{"bb",20}}; printf("[%u,%u]\n",filled,&filled); printf("[%u,%u]\n",filled[0],&
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
printf("[%u,%u]\n",filled+1,&filled+1);
printf("[%u,%u]\n",filled[1],&filled[1]);
printf
中的格式说明符%u
需要类型为unsigned int
的参数。您为它提供了完全不相关类型的参数:结构类型的指针和对象。因此,代码表现出未定义的行为。代码被破坏,其输出完全没有意义。试图分析或解释它没有多大意义。(解释当然存在,但与主要问题无关。)
至于数组在内存中的排列方式。。。StackOverflow充满了对这个问题的重复回答。只需进行搜索。格式说明符
%u
在printf
中需要类型为unsigned int
的参数。您为它提供了完全不相关类型的参数:结构类型的指针和对象。因此,代码表现出未定义的行为。代码被破坏,其输出完全没有意义。试图分析或解释它没有多大意义。(解释当然存在,但与主要问题无关。)
至于数组在内存中的排列方式。。。StackOverflow充满了对这个问题的重复回答。只需进行搜索。您的代码
[2293552,2293552]
[4206592,10]
[2293560,2293568]
[4206595,20]
在进一步讨论这个问题之前,我们需要了解一下“struct”是什么样子的。你没有给出定义,所以我假设它是
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
因此,filled
是这些对象的数组:
struct abc {
const char* str;
int i;
};
filled[0]
引用空间中的第一个结构abc
filled[] = {
struct abc { str = "aa", i = 10 },
struct abc { str = "bb", i = 20 }
};
在内存中,在32位构建中,这些将被布局,其中[…]表示一个字节:
{ str = "aa", i = 10 }
在64位系统上,它们的布局如下
[ptr][ptr][ptr][ptr][i][i][i][i]
构成str
和i
的字节的确切顺序将取决于体系结构
现在,你的代码
[ptr][ptr][ptr][ptr][ptr][ptr][ptr][ptr][i][i][i][i]
printf有一个限制。底层函数实际上看不到您的参数-它只获取堆栈上的数据,并使用打印格式作为指导
最终出现的可怕错误是,您将结构作为printf参数传递
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
filled[0]
解析为结构abc
发生的情况是,程序将filled[0]的值放入堆栈以供printf使用。格式掩码中的第一个%u使用str
组件,第二个使用i
如果这是您的完整计划:
printf("[%u,%u]", filled[0], &filled[0]);
当你这样做的时候
prog.c: In function ‘main’:
prog.c:12:5: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘struct abc’ [-Wformat=]
printf("filled[0] = %p\n", filled[0]);
该程序执行以下操作:
printf("[%u, %u]\n", filled[0], &filled[0]);
生成的堆栈如下所示
printf从不使用“&filled[0]”的值,因为您没有指定正确的格式来读取堆栈上的数据。如果你用
push stack (const char*) "[%u, %u]\n" // in 32-bit, 4-bytes of pointer.
push stack (struct abc) filled[0] // pushes the entire of filled[0], str and i, 8 bytes.
push stack (struct abc*) &filled[0] // pushes another 4 bytes.
然后您将获得更有意义的数据,但这是实现结果的一种危险方式,因为它对数据布局和堆栈进行了大量假设
从根本上说,您的问题在于您正在这样做:
printf(“%u”,填入[0])
其中填充的[0]不是简单的数据类型。您的代码
[2293552,2293552]
[4206592,10]
[2293560,2293568]
[4206595,20]
在进一步讨论这个问题之前,我们需要了解一下“struct”是什么样子的。你没有给出定义,所以我假设它是
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
因此,filled
是这些对象的数组:
struct abc {
const char* str;
int i;
};
filled[0]
引用空间中的第一个结构abc
filled[] = {
struct abc { str = "aa", i = 10 },
struct abc { str = "bb", i = 20 }
};
在内存中,在32位构建中,这些将被布局,其中[…]表示一个字节:
{ str = "aa", i = 10 }
在64位系统上,它们的布局如下
[ptr][ptr][ptr][ptr][i][i][i][i]
构成str
和i
的字节的确切顺序将取决于体系结构
现在,你的代码
[ptr][ptr][ptr][ptr][ptr][ptr][ptr][ptr][i][i][i][i]
printf有一个限制。底层函数实际上看不到您的参数-它只获取堆栈上的数据,并使用打印格式作为指导
最终出现的可怕错误是,您将结构作为printf参数传递
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
filled[0]
解析为结构abc
发生的情况是,程序将filled[0]的值放入堆栈以供printf使用。格式掩码中的第一个%u使用str
组件,第二个使用i
如果这是您的完整计划:
printf("[%u,%u]", filled[0], &filled[0]);
当你这样做的时候
prog.c: In function ‘main’:
prog.c:12:5: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘struct abc’ [-Wformat=]
printf("filled[0] = %p\n", filled[0]);
该程序执行以下操作:
printf("[%u, %u]\n", filled[0], &filled[0]);
生成的堆栈如下所示
printf从不使用“&filled[0]”的值,因为您没有指定正确的格式来读取堆栈上的数据。如果你用
push stack (const char*) "[%u, %u]\n" // in 32-bit, 4-bytes of pointer.
push stack (struct abc) filled[0] // pushes the entire of filled[0], str and i, 8 bytes.
push stack (struct abc*) &filled[0] // pushes another 4 bytes.
然后您将获得更有意义的数据,但这是实现结果的一种危险方式,因为它对数据布局和堆栈进行了大量假设
从根本上说,您的问题在于您正在这样做:
printf(“%u”,填入[0])
其中filled[0]不是简单的数据类型。你能解释一下&filled[0]给出10..的原因吗?@Rakesh_Kumar没有任何解释。AndreyT已经提到,您的代码表现出未定义的行为。实际上,有一个非常简单的解释——他正在按值传递一个结构,10来自他的结构。@Rakesh_Kumar:“原因”这是由于前面的参数
printf
出现问题而导致printf
参数堆栈区域完全错位。(如果您试图打印&filled[0]
作为第一个参数,输出将不同。)换句话说,正如我前面所说,您的程序打印的垃圾相当随机,无法以任何与主要问题相关的方式进行解释。您能解释一下&filled[0]给出10..的行为吗?@Rakesh_Kumar没有解释