我可以在结构中使用 "int" 作为我的动态数组吗?
can i use "int" as my dynamic array inside a struct?
一般来说,我正在尝试分配 first.a 和 first.b 的值
在 struct secon.
中的数组
typedef struct {
int a;
int b;
} firs;
//secon is my struct which contains dynamic array
//can i use int here ?
typedef struct {
int *aa;
int *bb;
} secon;
//pointer to secon intialised to NULL;
secon* sp=NULL;
int main()
{
firs first;
//plz assume 2 is coming from user ;
sp=malloc(sizeof(secon)*2);
//setting values
first.a=10;
first.b=11;
/* what i'm trying to do is assign values of first.a and first.b to my
dynamically created array*/
/* plz assume first.a and first.b are changing else where .. that means ,not
all arrays will have same values */
/* in general , i'm trying to allocate values of first.a and first.b
to a array's in struct second. */
for(int i=0; i<2; i++) {
*( &(sp->aa ) + (i*4) ) = &first.a;
*( &(sp->bb ) + (i*4) ) = &first.b;
}
for(int i=0; i<2; i++) {
printf("%d %d \n", *((sp->aa) + (i*4) ),*( (sp->bb) +(i*4) ) );
}
return 0;
}
我的输出:
10 11
4196048 0
我的代码有问题:
1.我的代码有什么问题?
2. 我可以在动态数组的结构中使用 int 吗?
3.有哪些选择?
4. 为什么我得不到正确答案?
这完全是一团糟。如果要访问 secon
的数组,请使用 []
for(int i=0;i<2;i++)
{
sp[i].aa = &first.a; // Same pointer both times
sp[i].bb = &first.b;
}
您有两个指向 first
中值的指针副本,它们指向相同的 value
for(int i=0;i<2;i++)
{
sp[i].aa = malloc(sizeof(int)); // new pointer each time
*sp[i].aa = first.a; // assigned with the current value
sp[i].bb = malloc(sizeof(int));
*sp[i].bb = first.b;
}
但是编译器允许假设 first 不变,并且允许重新排序这些表达式,所以你不能保证你的 secon
s[=18= 中有不同的值]
无论哪种方式,当你读回第二个值时,你仍然可以使用 []
for(int i=0;i<2;i++)
{
printf("%d %d \n",*sp[i].aa ),*sp[i].bb );
}
您对 C 中指针算法的工作原理的理解似乎有误。数据布局假设也存在问题。最后,存在可移植性问题和错误的语法选择,使理解变得复杂。
我假设机智这个表达式:*( &(sp->aa ) + (i*4) )
你试图通过获取第 0 个项目的地址然后添加一个字节偏移量来访问数组中的第 i
个项目它。这是错误的三个原因:
- 你假设在内存中sp[0].aa之后是sp[1].aa,但是你忘记了中间还有sp[0].bb
- 您假设
int
的大小始终为 4 个字节,这是不正确的。
- 您假设将
int
添加到 secon*
将为您提供一个偏移指定字节数的指针,而实际上它将偏移指定数量的记录,大小为 secon
.
您看到的第二行输出是来自未分配堆内存的随机垃圾,因为当 i == 1
您的构造引用的内存超出了为 *secon
分配的限制。
要访问指针引用的数组的第 i
项,请使用 []
:
secon[0].aa
等同于(secon +0)->aa
,secon[1].aa
等同于(secon+1)->aa
.
Grigory Rechistov 在理清代码方面做得非常出色,您可能应该接受他的回答,但我想强调一点。
在 C 指针算法中,偏移量总是以指向的类型的大小为单位。除非指针的类型是 char*
或 void*
如果你发现自己乘以类型的大小,几乎可以肯定你做错了。
如果我有
int a[10];
int *p = &(a[5]);
int *q = &(a[7]);
那么a[6]
就等于*(p + 1)
不是*(p + 1 * sizeof(int))
。同样 a[4]
是 *(p - 1)
此外,当指针都指向同一个数组中的对象并且应用相同的规则时,您可以减去指针;结果以指向的类型的大小为单位。 q - p
是 2
,而不是 2 * sizeof(int)
。将示例中的类型 int
替换为任何其他类型,并且 p - q
将始终为 2
。例如:
struct Foo { int n ; char x[37] ; };
struct Foo a[10];
struct Foo *p = &(a[5]);
struct Foo *q = &(a[7]);
q - p
仍然是 2
。顺便说一句,永远不要试图在任何地方对类型的大小进行硬编码。如果你想要 malloc
这样的结构:
struct Foo *r = malloc(41); // int size is 4 + 37 chars
不要。
首先,sizeof(int)
不能保证是4。其次,即使是,sizeof(struct Foo)
也不能保证是41。编译器通常会向struct
类型添加填充以确保成员正确对齐。在这种情况下,几乎可以肯定编译器将在 struct Foo
的末尾添加 3 个字节(或 7 个字节)的填充,以确保在数组中,n
成员的地址对齐到 int 的大小。总是总是总是使用sizeof
.
一般来说,我正在尝试分配 first.a 和 first.b 的值 在 struct secon.
中的数组typedef struct {
int a;
int b;
} firs;
//secon is my struct which contains dynamic array
//can i use int here ?
typedef struct {
int *aa;
int *bb;
} secon;
//pointer to secon intialised to NULL;
secon* sp=NULL;
int main()
{
firs first;
//plz assume 2 is coming from user ;
sp=malloc(sizeof(secon)*2);
//setting values
first.a=10;
first.b=11;
/* what i'm trying to do is assign values of first.a and first.b to my
dynamically created array*/
/* plz assume first.a and first.b are changing else where .. that means ,not
all arrays will have same values */
/* in general , i'm trying to allocate values of first.a and first.b
to a array's in struct second. */
for(int i=0; i<2; i++) {
*( &(sp->aa ) + (i*4) ) = &first.a;
*( &(sp->bb ) + (i*4) ) = &first.b;
}
for(int i=0; i<2; i++) {
printf("%d %d \n", *((sp->aa) + (i*4) ),*( (sp->bb) +(i*4) ) );
}
return 0;
}
我的输出:
10 11
4196048 0
我的代码有问题: 1.我的代码有什么问题? 2. 我可以在动态数组的结构中使用 int 吗? 3.有哪些选择? 4. 为什么我得不到正确答案?
这完全是一团糟。如果要访问 secon
的数组,请使用 []
for(int i=0;i<2;i++)
{
sp[i].aa = &first.a; // Same pointer both times
sp[i].bb = &first.b;
}
您有两个指向 first
中值的指针副本,它们指向相同的 value
for(int i=0;i<2;i++)
{
sp[i].aa = malloc(sizeof(int)); // new pointer each time
*sp[i].aa = first.a; // assigned with the current value
sp[i].bb = malloc(sizeof(int));
*sp[i].bb = first.b;
}
但是编译器允许假设 first 不变,并且允许重新排序这些表达式,所以你不能保证你的 secon
s[=18= 中有不同的值]
无论哪种方式,当你读回第二个值时,你仍然可以使用 []
for(int i=0;i<2;i++)
{
printf("%d %d \n",*sp[i].aa ),*sp[i].bb );
}
您对 C 中指针算法的工作原理的理解似乎有误。数据布局假设也存在问题。最后,存在可移植性问题和错误的语法选择,使理解变得复杂。
我假设机智这个表达式:*( &(sp->aa ) + (i*4) )
你试图通过获取第 0 个项目的地址然后添加一个字节偏移量来访问数组中的第 i
个项目它。这是错误的三个原因:
- 你假设在内存中sp[0].aa之后是sp[1].aa,但是你忘记了中间还有sp[0].bb
- 您假设
int
的大小始终为 4 个字节,这是不正确的。 - 您假设将
int
添加到secon*
将为您提供一个偏移指定字节数的指针,而实际上它将偏移指定数量的记录,大小为secon
.
您看到的第二行输出是来自未分配堆内存的随机垃圾,因为当 i == 1
您的构造引用的内存超出了为 *secon
分配的限制。
要访问指针引用的数组的第 i
项,请使用 []
:
secon[0].aa
等同于(secon +0)->aa
,secon[1].aa
等同于(secon+1)->aa
.
Grigory Rechistov 在理清代码方面做得非常出色,您可能应该接受他的回答,但我想强调一点。
在 C 指针算法中,偏移量总是以指向的类型的大小为单位。除非指针的类型是 char*
或 void*
如果你发现自己乘以类型的大小,几乎可以肯定你做错了。
如果我有
int a[10];
int *p = &(a[5]);
int *q = &(a[7]);
那么a[6]
就等于*(p + 1)
不是*(p + 1 * sizeof(int))
。同样 a[4]
是 *(p - 1)
此外,当指针都指向同一个数组中的对象并且应用相同的规则时,您可以减去指针;结果以指向的类型的大小为单位。 q - p
是 2
,而不是 2 * sizeof(int)
。将示例中的类型 int
替换为任何其他类型,并且 p - q
将始终为 2
。例如:
struct Foo { int n ; char x[37] ; };
struct Foo a[10];
struct Foo *p = &(a[5]);
struct Foo *q = &(a[7]);
q - p
仍然是 2
。顺便说一句,永远不要试图在任何地方对类型的大小进行硬编码。如果你想要 malloc
这样的结构:
struct Foo *r = malloc(41); // int size is 4 + 37 chars
不要。
首先,sizeof(int)
不能保证是4。其次,即使是,sizeof(struct Foo)
也不能保证是41。编译器通常会向struct
类型添加填充以确保成员正确对齐。在这种情况下,几乎可以肯定编译器将在 struct Foo
的末尾添加 3 个字节(或 7 个字节)的填充,以确保在数组中,n
成员的地址对齐到 int 的大小。总是总是总是使用sizeof
.