从预分配内存中直接读取 C 中的结构失败
Doing a direct struct read in C from preallocated memory failed
我假设它又是一个指针问题,但我想在这里做的是有一个函数搜索内存来查看 IP 地址是否存在,如果不存在则随机内存 space 为 IP 地址保留,返回零。该函数将 IP 地址作为字符串作为第一个参数,第二个参数指向结构。当执行 main() 函数时,result 应该等于 0,result2 应该等于 1,但是我却崩溃了,我认为这与我分配指针的方式有关?
在这个片段中...
ip=(iprec*)p;
我正在尝试设置传递给函数的 iprec 结构(之前由 malloc 分配),但我不确定在该语句的何处添加或删除星号。
这是代码的其余部分。
char *shma;
typedef struct{
unsigned char u;
unsigned char a[4];
unsigned int otherdata;
} iprec;
static int loadip(char* remoteip,iprec *ip){
char *p=shma;
int v=0;
char *ep;
unsigned char a[4];
sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3]);
int i,n;int sz=5000;
int szr=sizeof(iprec);
for (i=3;i<sz;i+=szr){
ip=(iprec*)p;
if (ip->u=='Y'){
for (n=0;n<=4;n++){
if (a[n]!=ip->a[n]){break;}
}
if (n >= 3){v=1;break;}
}else{
ep=p;
}
p+=szr;
}
if (v==0){
ip=(iprec*)ep;
for (n=0;n<=3;n++){
ip->a[n]=a[n];
}
}
return v;
}
int main(){
char *shma=(char*)malloc(5000); //alloc 5000 bytes for example.
iprec *x=(iprec*)malloc(sizeof(iprec));
int result=loadip("127.0.0.1",x);
int result2=loadip("127.0.0.1",x);
}
替换
sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3])
;
与
sscanf(remoteip,"%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3]);
sccanf
需要指针类型参数。
shma
应该是全局的。
我还没有对你的代码进行完整的分析,但这是你崩溃的根源。最下面是分辨率
分析
在您的代码段顶部,您有
char *shma;
这是一个名为 shma 的文件范围(全局)对象,具有静态持续时间存储。它在 main() 执行之前被初始化为 0。
然后,在主要部分,您有:
int main(){
char *shma=(char*)malloc(5000); //alloc 5000 bytes for example.
在这里声明一个名为 shma 的新对象。它具有块作用域(仅存在于 main 的上下文中),具有自动存储功能。你从 malloc() 给它分配一个指针。然后你调用 loadip
.
loadip
有
char *p=shma;
它声明了一个名为 p 的新对象,具有块范围(存在于 loadip 中)和自动存储。您将其设置为 shma
。 注意 这是分配全局 shma,而不是 main
中的那个,因为 main 中的那个只存在于 main 中,而 loadip
在 main 之外。全局 shma 是 0,所以现在 p 也是 0(至少对于你的第一个循环)。
然后,你做:
ip=(iprec*)p;
所以,因为 p 是 0,所以现在 ip 是 0。在下一行:
if (ip->u=='Y'){
您正在取消引用 ip
以获取成员 u
。在大多数系统上,这种取消引用将导致分段错误(或类似的内存访问冲突),因为您实际上已经取消引用了 NULL
(0 地址)。
修复此问题
改变
int main(){
char *shma=(char*)malloc(5000); //alloc 5000 bytes for example.
进入
int main(){
shma=(char*)malloc(5000); //alloc 5000 bytes for example.
这将导致 main 分配给全局 shma
而不是创建新的本地。
自从我完成 C 后有一段时间了,但有一些想法:
char *p=shma;
但 shma 尚未初始化 - 因此 "ip=(iprec*)p;" 意味着 ip 将不是有效值。
unsigned char a[4];
sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3]);
您需要接收变量的地址(即 &a[0]、&a[1]、...)。
此外,由于 '%d' 将写入 4 字节整数(scanf 不知道它是一个 char 数组),最好使用 "int a[4]"
ip=(iprec*)p;
但是 ip 是一个输入参数 - 所以在这里您要覆盖(即丢弃)用户在第二个参数中提供的任何值。
if (v==0){
ip=(iprec*)ep;
即使 v=0,ep 仍然有可能没有被初始化(eg.if 所有 ip->u == 'Y' 但 a 数组在第一个或第二个不同值)
我假设它又是一个指针问题,但我想在这里做的是有一个函数搜索内存来查看 IP 地址是否存在,如果不存在则随机内存 space 为 IP 地址保留,返回零。该函数将 IP 地址作为字符串作为第一个参数,第二个参数指向结构。当执行 main() 函数时,result 应该等于 0,result2 应该等于 1,但是我却崩溃了,我认为这与我分配指针的方式有关?
在这个片段中...
ip=(iprec*)p;
我正在尝试设置传递给函数的 iprec 结构(之前由 malloc 分配),但我不确定在该语句的何处添加或删除星号。
这是代码的其余部分。
char *shma;
typedef struct{
unsigned char u;
unsigned char a[4];
unsigned int otherdata;
} iprec;
static int loadip(char* remoteip,iprec *ip){
char *p=shma;
int v=0;
char *ep;
unsigned char a[4];
sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3]);
int i,n;int sz=5000;
int szr=sizeof(iprec);
for (i=3;i<sz;i+=szr){
ip=(iprec*)p;
if (ip->u=='Y'){
for (n=0;n<=4;n++){
if (a[n]!=ip->a[n]){break;}
}
if (n >= 3){v=1;break;}
}else{
ep=p;
}
p+=szr;
}
if (v==0){
ip=(iprec*)ep;
for (n=0;n<=3;n++){
ip->a[n]=a[n];
}
}
return v;
}
int main(){
char *shma=(char*)malloc(5000); //alloc 5000 bytes for example.
iprec *x=(iprec*)malloc(sizeof(iprec));
int result=loadip("127.0.0.1",x);
int result2=loadip("127.0.0.1",x);
}
替换
sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3])
;
与
sscanf(remoteip,"%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3]);
sccanf
需要指针类型参数。
shma
应该是全局的。
我还没有对你的代码进行完整的分析,但这是你崩溃的根源。最下面是分辨率
分析
在您的代码段顶部,您有
char *shma;
这是一个名为 shma 的文件范围(全局)对象,具有静态持续时间存储。它在 main() 执行之前被初始化为 0。
然后,在主要部分,您有:
int main(){
char *shma=(char*)malloc(5000); //alloc 5000 bytes for example.
在这里声明一个名为 shma 的新对象。它具有块作用域(仅存在于 main 的上下文中),具有自动存储功能。你从 malloc() 给它分配一个指针。然后你调用 loadip
.
loadip
有
char *p=shma;
它声明了一个名为 p 的新对象,具有块范围(存在于 loadip 中)和自动存储。您将其设置为 shma
。 注意 这是分配全局 shma,而不是 main
中的那个,因为 main 中的那个只存在于 main 中,而 loadip
在 main 之外。全局 shma 是 0,所以现在 p 也是 0(至少对于你的第一个循环)。
然后,你做:
ip=(iprec*)p;
所以,因为 p 是 0,所以现在 ip 是 0。在下一行:
if (ip->u=='Y'){
您正在取消引用 ip
以获取成员 u
。在大多数系统上,这种取消引用将导致分段错误(或类似的内存访问冲突),因为您实际上已经取消引用了 NULL
(0 地址)。
修复此问题
改变
int main(){
char *shma=(char*)malloc(5000); //alloc 5000 bytes for example.
进入
int main(){
shma=(char*)malloc(5000); //alloc 5000 bytes for example.
这将导致 main 分配给全局 shma
而不是创建新的本地。
自从我完成 C 后有一段时间了,但有一些想法:
char *p=shma;
但 shma 尚未初始化 - 因此 "ip=(iprec*)p;" 意味着 ip 将不是有效值。
unsigned char a[4];
sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3]);
您需要接收变量的地址(即 &a[0]、&a[1]、...)。 此外,由于 '%d' 将写入 4 字节整数(scanf 不知道它是一个 char 数组),最好使用 "int a[4]"
ip=(iprec*)p;
但是 ip 是一个输入参数 - 所以在这里您要覆盖(即丢弃)用户在第二个参数中提供的任何值。
if (v==0){
ip=(iprec*)ep;
即使 v=0,ep 仍然有可能没有被初始化(eg.if 所有 ip->u == 'Y' 但 a 数组在第一个或第二个不同值)