V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gooooood
V2EX  ›  C

求帮忙看一下这个 C 代码为什么会段错误!

  •  
  •   gooooood · 192 天前 · 1358 次点击
    这是一个创建于 192 天前的主题,其中的信息可能已经有所发展或是发生改变。
    typedef struct {
        int width;
        int height;
        int depth;
    } INFO_T;
    
    int Send(int infoNum, const INFO_T *pInfo[])
    {
    	INFO_T tInfo;
    	for (int m = 0; m < infoNum; m++) {
    		memcpy(&tInfo, &pInfo[m], sizeof(INFO_T));
    		printf("info=%d \n", tInfo.width);  //这条语句是正常的
    		printf("info=%d \n", pInfo[m]->width); //按理说这条和上面一条是等价的,但是加入这条语句后就会 core 崩溃
    	}
    }
    
    第 1 条附言  ·  191 天前

    我感觉是我的表达不够准确,重述一下:其实我是想探索如何使用结构体二级指针进行传参。 通过一番尝试,我发现使用结构体二级指针是有些多余的,直接使用 INFO_S info[]作为传参即可。

    如果想使用结构体二级指针,正确引用的方式为:

    printf("info=%d %d\n", (((INFO_T *)pInfo)+m)->width,((INFO_T *)pInfo+m)->height);
    

    以下是我的调试代码与结果:

    #include <stdio.h>
    #include <string.h>
    typedef struct {
        int width;
        int height;
    } INFO_T;
    int Send(int infoNum, const INFO_T *pInfo[])
    {
    	printf("func addr=%#x %#x %#x %#x %#x %#x\n", pInfo, *pInfo, &pInfo[0], pInfo, &pInfo[1],pInfo+1);
    	for (int m = 0; m < infoNum; m++) {
    		printf("info=%d %d\n", (((INFO_T *)pInfo)+m)->width,((INFO_T *)pInfo+m)->height);
    	}
    	return 0;
    }
    int main()
    {
       printf("Hello, World! \n");
       INFO_T atInfo[2];
    	atInfo[0].width = 9;atInfo[0].height = 2;
    	atInfo[1].width = 3;atInfo[1].height = 4;
    	printf("main addr =%#x %#x %#x %#x %#x\n", atInfo, &atInfo, &atInfo[0].width, &atInfo[0].height,&atInfo[1] );
    	Send(2,(const INFO_T**)atInfo);
       return 0;
    }
    
    Hello, World! 
    main addr =0xeb58c490 0xeb58c490 0xeb58c490 0xeb58c494 0xeb58c498
    func addr=0xeb58c490 0x9 0xeb58c490 0xeb58c490 0xeb58c498 0xeb58c498
    info=9 2
    info=3 4
    

    Anyway, 感谢大家的帮助~

    16 条回复    2023-10-20 14:03:04 +08:00
    codehz
        1
    codehz  
       192 天前
    你这类型不对吧 INFO_T *pInfo[]
    memcpy 的是 INFO_T *的 pInfo[m]到 INFO_T 的 tInfo 。。。
    DuckBurrito
        2
    DuckBurrito  
       192 天前
    我没理解错的话应该改成下面这样子吧

    memcpy(&tInfo, pInfo[m], sizeof(INFO_T));

    像你这样子写实际上是在复制一个 INFO_T 指针的值到 tInfo 中,并没有复制 INFO_T 结构体
    yianing
        3
    yianing  
       192 天前
    tInfo 是一个栈上内存,第一个 printf 只经过一次寻址,只是读栈上部分不会出错,第二个 printf 参数是二级指针对应的数据需要经过两次寻址,可能是你参数有问题
    woooooOOOO
        4
    woooooOOOO  
       192 天前
    memcpy(&tInfo, pInfo[m], sizeof(INFO_T));
    pInfo[m]就是一个地址,不用再取&
    lsry
        5
    lsry  
       192 天前
    函數參數用的 INFO_T *pInfo[],由於數組作參數,這代表是個 二級指針 INFO_T **,這可能有兩種情況:
    1. 代表二維數組,pInfo[m]->width 這就不對了,pinfo[m] 代表一維數組,要 pInfo[m][k] 才是 INFO_T struct ;
    2. 對一維數組再取一次地址,pInfo[m]->width 就要改成 (*pInfo)[m];
    具體取決於你的代碼
    DiamondY
        6
    DiamondY  
       191 天前
    要看一下传入 Send()里面的 pInfo 是啥东西,从上下文猜测的话,应该搞混了指针和指针数组
    gooooood
        7
    gooooood  
    OP
       191 天前
    @codehz 确实,实际上传参使用 INFO_T pInfo[]就可以了,使用 INFO_T *pInfo[]有点多此一举了
    gooooood
        8
    gooooood  
    OP
       191 天前
    @lsry 尝试了,这样也有问题。正确的应该是:(((INFO_T *)pInfo)+m)->width
    gooooood
        9
    gooooood  
    OP
       191 天前
    @DiamondY 有点搞混了
    gooooood
        10
    gooooood  
    OP
       191 天前
    @DuckBurrito 好像两种都可以诶
    gooooood
        11
    gooooood  
    OP
       191 天前
    @yianing 确实是参数错误引起的问题
    gooooood
        12
    gooooood  
    OP
       191 天前
    @woooooOOOO 我打印了两个值,结果是一样的
    araraloren
        13
    araraloren  
       191 天前
    Your test code is totally wrong.
    araraloren
        14
    araraloren  
       191 天前
    realJamespond
        15
    realJamespond  
       191 天前
    tInfo 已经分配内存,pInfo[m]内存越界了肯定报错,怎么没区别?
    gooooood
        16
    gooooood  
    OP
       190 天前
    @araraloren agree.Thanks
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1690 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:00 · PVG 08:00 · LAX 17:00 · JFK 20:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.