从预分配的内存中执行C中的直接结构读取失败

时间:2015-02-11 04:54:32

标签: c struct

我再次假设它有一个指针问题,但我在这里尝试做的是有一个函数搜索内存来查看是否存在IP地址,如果它没有,那么为IP地址保留随机存储空间,返回零。该函数将IP地址作为字符串作为第一个参数,第二个参数指向结构。当执行main()函数时,结果应该等于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);
}

3 个答案:

答案 0 :(得分:3)

  1. 替换

    sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3]);

  2. sscanf(remoteip,"%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3]);
    

    sccanf需要指针类型参数。

    1. shma应该是全球性的。

答案 1 :(得分:2)

我还没有对您的代码进行全面分析,但这是您崩溃的原因。底部是分辨率

分析

在您的代码段顶部,您有

char *shma;

这是一个名为shma的文件范围(全局)对象,具有静态持续时间存储。它在main()执行之前被初始化为0。

然后,在main中,你有:

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.

这将导致主要分配给全局shma,而不是创建新的本地。{/ p>

答案 2 :(得分:1)

我已经做了一段时间,但是有些想法:

char *p=shma;

但shma尚未初始化 - 因此&#34; ip =(iprec *)p;&#34;表示ip不是有效值。

unsigned char a[4];
sscanf(remoteip,"%d.%d.%d.%d",a[0],a[1],a[2],a[3]);

您需要接收变量的地址(即&amp; a [0],&amp; a [1],...)。 此外,因为&#39;%d&#39;将写入4个字节的整数(scanf不知道它是一个字符数组),最好有&#34; int a [4]&#34;

ip=(iprec*)p;

但ip是一个输入参数 - 所以在这里你要覆盖(即丢弃)用户在第二个参数中提供的任何值。

if (v==0){
    ip=(iprec*)ep;

即使v = 0,仍然可能没有初始化ep(例如,如果所有ip-> u ==&#39; Y&#39;但是a-arrays在第一个或第二个上有所不同值)