OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4608|回复: 20

一个C语言问题,为什么会崩溃

[复制链接]

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
发表于 2017-12-16 07:45:08 | 显示全部楼层 |阅读模式
1金钱
#include <stdio.h>
#include <stdlib.h>

unsigned char Data[] = {1,2,3,4,5,8,4,7};
typedef struct {
    unsigned char cnt;
    unsigned char ValidFlag;
    unsigned char buf[250];
} WifiBuf;
typedef struct {
    WifiBuf WsnBuf[5];
    unsigned char header;
} tagWifiBuf;
tagWifiBuf WsnDataBuf;


unsigned char PutsWsnData2Buf(unsigned char *buf,  unsigned char len)
{
     unsigned char i;
     unsigned char PutCount = 0;
    WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt = 0;
    for (i = 0; i < len; i++) {
        if (WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt < 250) {
            WsnDataBuf.WsnBuf[WsnDataBuf.header].buf = buf;
            WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt++;
            if (WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt >= 250) {
                WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt = 0;
            }
        }
        else {
            break;
        }
    }
    PutCount = WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt;
    WsnDataBuf.WsnBuf[WsnDataBuf.header].ValidFlag =1;
    WsnDataBuf.header ++;
    if (WsnDataBuf.header >=5) {
        WsnDataBuf.header  = 0;
    }
    return(PutCount);
}

unsigned char GetsWsnDataFromBuf(unsigned char **Ptr)
{
     unsigned char i = 0,j = 0;
    for (j = 0; j <5; j++) {
        if(WsnDataBuf.WsnBuf[j].ValidFlag == 1){
            Ptr = &(WsnDataBuf.WsnBuf[j].buf[0]);
            i= WsnDataBuf.WsnBuf[j].cnt;
            WsnDataBuf.WsnBuf[j].ValidFlag = 0;
            WsnDataBuf.WsnBuf[j].cnt =0;
            break;
        }
    }
    return(i);
}


int main()
{
    static unsigned char *Ptr =NULL ;
    int cnt =0;
    PutsWsnData2Buf(Data,sizeof(Data)/sizeof(Data[0]));
    /*这里为什么不能使用Ptr 传递出数组的地址
       程序运行就崩溃了
    */

    cnt = GetsWsnDataFromBuf(Ptr);
    printf("cnt = %d\n",cnt);
    for(int i =0;i <cnt;i++)
        printf("i = %d\n",*(Ptr +i));
    return 0;
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8062
金钱
8062
注册时间
2014-8-13
在线时间
1597 小时
发表于 2017-12-16 08:01:23 | 显示全部楼层
PutsWsnData2Buf中的WsnDataBuf未定义,要么定义一个,要么搞成全局静态什么的
回复

使用道具 举报

7

主题

247

帖子

0

精华

高级会员

Rank: 4

积分
745
金钱
745
注册时间
2016-1-20
在线时间
78 小时
发表于 2017-12-16 09:05:01 | 显示全部楼层
本帖最后由 footprint 于 2017-12-16 09:10 编辑

unsigned char GetsWsnDataFromBuf(unsigned char **Ptr),参数是二级指针吧,static unsigned char *Ptr =NULL tr 是一个一级指针,且是空指针。1,没有任何处理编译可以通过吗?2,空指针没有看到赋值,做参数使用意义何在?我是个新手,没看明白,楼主有时间指教一二。tst.c
c:\users\administrator\desktop\tst.c(24) : error C2106: '=' : left operand must be l-value
c:\users\administrator\desktop\tst.c(48) : warning C4047: '=' : 'unsigned char ** ' differs in levels of indirection from 'unsigned char *'
c:\users\administrator\desktop\tst.c(67) : warning C4047: 'function' : 'unsigned char ** ' differs in levels of indirection from 'unsigned char *'
c:\users\administrator\desktop\tst.c(67) : warning C4024: 'GetsWsnDataFromBuf' : different types for formal and actual parameter 1
c:\users\administrator\desktop\tst.c(69) : error C2143: syntax error : missing ';' before 'type'
c:\users\administrator\desktop\tst.c(69) : error C2143: syntax error : missing ';' before 'type'
c:\users\administrator\desktop\tst.c(69) : error C2143: syntax error : missing ')' before 'type'
c:\users\administrator\desktop\tst.c(69) : error C2143: syntax error : missing ';' before 'type'
c:\users\administrator\desktop\tst.c(69) : error C2065: 'i' : undeclared identifier
c:\users\administrator\desktop\tst.c(69) : warning C4552: '<' : operator has no effect; expected operator with side-effect
c:\users\administrator\desktop\tst.c(69) : error C2059: syntax error : ')'
c:\users\administrator\desktop\tst.c(70) : error C2146: syntax error : missing ';' before identifier 'printf'
Error executing cl.exe.

tst.obj - 8 error(s), 4 warning(s)


测试了一下,编译都不通过,何谈程序崩溃!


回复

使用道具 举报

7

主题

162

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2017-4-6
在线时间
67 小时
发表于 2017-12-16 10:12:47 | 显示全部楼层
PTR的值是0,*ptr的意思就是取地址0x0000_0000处的内容,在很多芯片里这个地址是不可读写的。
你传递了这个地址过去(先不管子函数是否有问题),对这个地址的内容进行了操作:Ptr = &(WsnDataBuf.WsnBuf[j].buf[0]);
所以就崩溃了。具体怎么崩溃的,这里就不是很清楚了,可能是总线上指令冲突?
回复

使用道具 举报

24

主题

695

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1666
金钱
1666
注册时间
2016-4-29
在线时间
266 小时
发表于 2017-12-16 13:09:16 | 显示全部楼层
有两个问题:1、ptr是个空指针。2、参数类型不符,一个是一级指针,一个是二级指针
回复

使用道具 举报

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
 楼主| 发表于 2017-12-16 22:16:20 | 显示全部楼层
footprint 发表于 2017-12-16 09:05
unsigned char GetsWsnDataFromBuf(unsigned char **Ptr),参数是二级指针吧,static unsigned char *Ptr = ...

我用CodeBlocks 编译是可以的
回复

使用道具 举报

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
 楼主| 发表于 2017-12-16 22:18:35 | 显示全部楼层
JUSTNIUB 发表于 2017-12-16 10:12
PTR的值是0,*ptr的意思就是取地址0x0000_0000处的内容,在很多芯片里这个地址是不可读写的。
你传递了这 ...

Ptr = &(WsnDataBuf.WsnBuf[j].buf[0]);
不应该是将&(WsnDataBuf.WsnBuf[j].buf[0])的地址付给Ptr吗?
回复

使用道具 举报

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
 楼主| 发表于 2017-12-16 22:22:13 | 显示全部楼层
d1z1y2 发表于 2017-12-16 13:09
有两个问题:1、ptr是个空指针。2、参数类型不符,一个是一级指针,一个是二级指针

Ptr初始化是空指针,但传递给函数后再函数里执行
Ptr = &(WsnDataBuf.WsnBuf[j].buf[0]);
不应该是将&(WsnDataBuf.WsnBuf[j].buf[0])的地址付给Ptr吗?

我是希望将(WsnDataBuf.WsnBuf[j].buf[0])地址 传递出函数,如果都使用一级指针,按照给函数船队形参的规则,可定是无法实现传递(WsnDataBuf.WsnBuf[j].buf[0]);地址的
回复

使用道具 举报

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
 楼主| 发表于 2017-12-16 22:51:03 | 显示全部楼层
mack13013 发表于 2017-12-16 08:01
PutsWsnData2Buf中的WsnDataBuf未定义,要么定义一个,要么搞成全局静态什么的

定义的有呀 tagWifiBuf WsnDataBuf

没定义的话编译肯定有问题的,
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8062
金钱
8062
注册时间
2014-8-13
在线时间
1597 小时
发表于 2017-12-17 04:40:59 | 显示全部楼层
wang12zhe 发表于 2017-12-16 22:51
定义的有呀 tagWifiBuf WsnDataBuf

没定义的话编译肯定有问题的,

定义了类型,定义了对象了吗?

那个定义只是说这个是一种什么格式的数据,但是没有一个用哪段内存放这种格式的定义,也没有说要放多少个。

你这个编译肯定不会通过的,我只是沿着你的程序读下来,这里是找到第一个问题。
你编译通过了的话,能发个截图吗?

你觉得定义了,是因为你把他当作静态的了,所以我才建议你搞成静态的。


找本C语言书看看吧
回复

使用道具 举报

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
 楼主| 发表于 2017-12-17 09:50:01 | 显示全部楼层
mack13013 发表于 2017-12-17 04:40
定义了类型,定义了对象了吗?

那个定义只是说这个是一种什么格式的数据,但是没有一个用哪段内存放这 ...

我所说的编译通过是没有错误,我编译的有警告,
无标题.png
回复

使用道具 举报

190

主题

401

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1291
金钱
1291
注册时间
2014-6-15
在线时间
144 小时
 楼主| 发表于 2017-12-17 09:52:09 | 显示全部楼层
mack13013 发表于 2017-12-17 04:40
定义了类型,定义了对象了吗?

那个定义只是说这个是一种什么格式的数据,但是没有一个用哪段内存放这 ...

附件是源文件

main.zip

774 Bytes, 下载次数: 184

回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8062
金钱
8062
注册时间
2014-8-13
在线时间
1597 小时
发表于 2017-12-17 10:21:41 | 显示全部楼层
wang12zhe 发表于 2017-12-17 09:50
我所说的编译通过是没有错误,我编译的有警告,

这是因为你的编译规则限定比较宽松导致的,这么宽松的规则设置只在特定的开发环境中才能使用。

下面是我编译的输出:
1>------ 已启动生成: 项目: WsnData2Buff, 配置: Debug Win32 ------
1>正在编译...
1>main.c
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(57) : warning C4047: “=”: “unsigned char **”与“unsigned char *”的间接级别不同
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(78) : warning C4047: “函数”: “unsigned char **”与“unsigned char *”的间接级别不同
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(78) : warning C4024: “GetsWsnDataFromBuf”: 形参和实参 1 的类型不同
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2143: 语法错误 : 缺少“;”(在“类型”的前面)
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2143: 语法错误 : 缺少“;”(在“类型”的前面)
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2143: 语法错误 : 缺少“)”(在“类型”的前面)
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2143: 语法错误 : 缺少“;”(在“类型”的前面)
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2065: “i”: 未声明的标识符
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : warning C4552: “<”: 运算符不起任何作用;应输入带副作用的运算符
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2065: “i”: 未声明的标识符
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2059: 语法错误 : “)”
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(80) : error C2143: 语法错误 : 缺少“;”(在“{”的前面)
1>d:\my documents\visual studio 2008\projects\wsndata2buff\wsndata2buff\main.c(81) : error C2065: “i”: 未声明的标识符
1>生成日志保存在“file://d:\My Documents\Visual Studio 2008\Projects\WsnData2Buff\WsnData2Buff\Debug\BuildLog.htm”
1>WsnData2Buff - 9 个错误,4 个警告
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
回复

使用道具 举报

24

主题

695

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1666
金钱
1666
注册时间
2016-4-29
在线时间
266 小时
发表于 2017-12-17 22:01:26 | 显示全部楼层
指针的指针也是一个指针,虽然占用空间一样,但这样用容易出错,更不便于阅读,
直接用那个全局的结构体多好啊,这样用阅读也不方便 ,
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7653
金钱
7653
注册时间
2016-11-30
在线时间
648 小时
发表于 2017-12-18 09:21:28 | 显示全部楼层
我就特不习惯看别人放着警告不管,直接就把程序烧进去了。没有错误,有警告就不代表你的程序没有问题了。除了定义未使用类的警告,其它的警告信息必须全部解决掉。不然程序很容易出问题,而且很难排查。系统都提示你代码有问题了,为什么不解决掉呢?舍近求远不可取。
回复

使用道具 举报

7

主题

247

帖子

0

精华

高级会员

Rank: 4

积分
745
金钱
745
注册时间
2016-1-20
在线时间
78 小时
发表于 2017-12-18 09:29:21 | 显示全部楼层
wang12zhe 发表于 2017-12-16 22:16
我用CodeBlocks 编译是可以的

那个编译器我没有用过,具体什么情况,我就解释不清楚了。希望早日解决问题,我也好长点知识。
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2017-12-14
在线时间
17 小时
发表于 2017-12-18 12:01:28 | 显示全部楼层
你的形参为二级指针,但在函数赋值的时候 你把他当做一级指针使用;肯定不对
5(2]Q3VUDRJLS%TPBK1I9VY.png
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2017-12-14
在线时间
17 小时
发表于 2017-12-18 12:06:28 | 显示全部楼层
还有 main()函数里的那里局部变量 unsigned char *Ptr,是需要赋初值的  指针变量没有初值,要么不对,要么很危险,也许这个指针指向了一个有用的数据 但后面你再把数据给这个指针,会破坏系统
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2017-12-14
在线时间
17 小时
发表于 2017-12-18 12:11:59 | 显示全部楼层
cnt = GetsWsnDataFromBuf(Ptr);  你没有给PTR赋值,在函数中引用,肯定不对的;并且引用的时候 你应该是   cnt =GetsWsnDataFromBuf(&ptr),二级指针指向的是一级指针的地址,并不是一级指针指向的数据的地址
回复

使用道具 举报

2

主题

10

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
425
金钱
425
注册时间
2016-4-17
在线时间
170 小时
发表于 2017-12-18 14:11:42 | 显示全部楼层
#include <stdio.h>
#include <stdlib.h>


unsigned char Data[] = {1,2,3,4,5,8,4,7};

typedef struct {
    unsigned char cnt;
    unsigned char ValidFlag;
    unsigned char buf[250];
} WifiBuf;

typedef struct {
    WifiBuf WsnBuf[5];
    unsigned char header;
} tagWifiBuf;

tagWifiBuf WsnDataBuf;




unsigned char PutsWsnData2Buf(unsigned char *buf,  unsigned char len)
{
     unsigned char i;
     unsigned char PutCount = 0;
    WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt = 0;
    for (i = 0; i < len; i++) {
        if (WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt < 250) {
            WsnDataBuf.WsnBuf[WsnDataBuf.header].buf[i] = buf[i];
            WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt++;
            if (WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt >= 250) {
                WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt = 0;
            }
        }
        else {
            break;
        }
    }
    PutCount = WsnDataBuf.WsnBuf[WsnDataBuf.header].cnt;
    WsnDataBuf.WsnBuf[WsnDataBuf.header].ValidFlag =1;
    WsnDataBuf.header ++;
    if (WsnDataBuf.header >=5) {
        WsnDataBuf.header  = 0;
    }
    return(PutCount);
}



unsigned char GetsWsnDataFromBuf(unsigned char **Ptr)
{
     unsigned char i = 0,j = 0;

    for (j = 0; j <5; j++) {
        if(WsnDataBuf.WsnBuf[j].ValidFlag == 1){
            *Ptr = &(WsnDataBuf.WsnBuf[j].buf[0]);
            i= WsnDataBuf.WsnBuf[j].cnt;
            WsnDataBuf.WsnBuf[j].ValidFlag = 0;
            WsnDataBuf.WsnBuf[j].cnt =0;
            break;
        }
    }
    return(i);
}




int main()
{
     unsigned char *Ptr ;
    int cnt =0;
        int i;
    PutsWsnData2Buf(Data,sizeof(Data)/sizeof(Data[0]));
    /*这里为什么不能使用Ptr 传递出数组的地址
       程序运行就崩溃了
    */
    cnt = GetsWsnDataFromBuf(&Ptr);
    printf("cnt = %d\n",cnt);
    for(i =0;i <cnt;i++)
        {
        printf("i = %d\n",*(Ptr+i));

    }

    return 0;
}

回复

使用道具 举报

7

主题

162

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2017-4-6
在线时间
67 小时
发表于 2017-12-18 18:18:16 | 显示全部楼层
wang12zhe 发表于 2017-12-16 22:18
Ptr = &(WsnDataBuf.WsnBuf[j].buf[0]);
不应该是将&(WsnDataBuf.WsnBuf[j].buf[0])的地址付给Ptr吗?

这条语句应该没问题,我之前思考存在漏洞。
不过这里可能存在传参上面的问题。

这里是Ptr(GetsWsnDataFromBuf) = Ptr(main),还是
Ptr(GetsWsnDataFromBuf) = &Ptr(main).
如果是后者,那还存在一个问题,即&这个符号它工作的时候它是否已经脱离了main函数,上下文里是否还包含了Ptr这个变量的信息。

以上都是猜测,实际情况看汇编应该能够发现。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-23 18:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表