标题:图书管理系统 查询图书部分
只看楼主
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
回复 10楼 吹水佬
修改一下,尽可能以防因文本不规范时引起读入内容越界。
2016-12-29 09:25
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 10楼 吹水佬
学习了原来把结构体成员放在指针数组里面就可以通过下标引用了就是把不连续的地址转化成连续的地址,这~感觉好好,学习了~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2016-12-29 10:40
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
得分:0 
回复 12楼 九转星河
这样做是有危险的。
相同的结构体定义在不同的编译器中会占据不同长度的内存空间。像题主这样的,结构体中都定义的是字符,也仅仅是对字符操作,这样问题不大。但如果结构体是不同类型的数据集合,是不能根据单个类型长度计算出其他数据位置的,好像涉及内存对齐概念,内存对齐是硬件特性决定的,而不同编译器会根据内存对齐特点预留不同的整数倍数的安全空间。
2016-12-29 11:15
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用xzlxzlxzl在2016-12-29 11:15:37的发言:

这样做是有危险的。
相同的结构体定义在不同的编译器中会占据不同长度的内存空间。像题主这样的,结构体中都定义的是字符,也仅仅是对字符操作,这样问题不大。但如果结构体是不同类型的数据集合,是不能根据单个类型长度计算出其他数据位置的,好像涉及内存对齐概念,内存对齐是硬件特性决定的,而不同编译器会根据内存对齐特点预留不同的整数倍数的安全空间。

举个有危险的例子看看
2016-12-29 11:20
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
得分:0 
回复 14楼 吹水佬
如下例,根据计算,结构体中字符数组长度为5,根据计算接下来的int变量在6的位置,但从代码中可以看到,在地址为8的位置才改变了int的值:
程序代码:
    #include <stdio.h>
struct aa
{
    char a[5];
    int b;
};
void main()
{
    aa bb;
    char *p;
    bb.a[0]='O';
    bb.a[1]='K';
    bb.a[2]=0;
    bb.b=123;
    p=(char*)&bb;
    p[5]=2;
    printf("%s\n%d\n",bb.a,bb.b);
    p[8]=2;
    printf("%s\n%d\n",bb.a,bb.b);
}
2016-12-29 11:34
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 

字节对齐问题,这样看看:


#include <stdio.h>
#pragma pack ()
struct ABC
{  
    char    a;  
    short   b;  
    int     c;  
};
main()
{
    printf("sizeof(char) = %d\n", sizeof(char));
    printf("sizeof(short) = %d\n", sizeof(short));
    printf("sizeof(int) = %d\n", sizeof(int));
    printf("sizeof(struct ABC) = %d\n", sizeof(struct ABC));
}


#include <stdio.h>
#pragma pack (1)
struct ABC
{  
    char    a;  
    short   b;  
    int     c;  
};
main()
{
    printf("sizeof(char) = %d\n", sizeof(char));
    printf("sizeof(short) = %d\n", sizeof(short));
    printf("sizeof(int) = %d\n", sizeof(int));
    printf("sizeof(struct ABC) = %d\n", sizeof(struct ABC));
}
2016-12-29 11:36
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
通常情况应用层的字节对齐应该不会有什么问题。
如果涉及到硬件memory操作或网络报文传输,最好使用#pragma pack (1)声明为1字节对齐。
2016-12-29 11:40
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 15楼 xzlxzlxzl
求解,有能规避这种风险的办法么~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2016-12-29 11:45
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用xzlxzlxzl在2016-12-29 11:34:22的发言:

如下例,根据计算,结构体中字符数组长度为5,根据计算接下来的int变量在6的位置,但从代码中可以看到,在地址为8的位置才改变了int的值:
    #include <stdio.h>
struct aa
{
    char a[5];
    int b;
};
void main()
{
    aa bb;
    char *p;
    bb.a[0]='O';
    bb.a[1]='K';
    bb.a[2]=0;
    bb.b=123;
    p=(char*)&bb;
    p[5]=2;
    printf("%s\n%d\n",bb.a,bb.b);
    p[8]=2;
    printf("%s\n%d\n",bb.a,bb.b);
}

    p[5]=2;
    p[8]=2;
对这两句有保留,个人认为这样去处理结构体不是好习惯,所以才易出问题。
结构体的使用要用结构体的成员名表示,尽量避免东指西指乱点一通。
2016-12-29 11:52
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
结构体按成员取址不会有问题的,不用担心字节对齐的问题。
2016-12-29 11:54



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-473067-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 1.126959 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved